target-i386: Enable clflushopt/clwb/pcommit instructions
[qemu/cris-port.git] / ui / vnc.c
bloba47f2b382ceb25a4df28f501884167a4e77e31e7
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
27 #include "vnc.h"
28 #include "vnc-jobs.h"
29 #include "trace.h"
30 #include "hw/qdev.h"
31 #include "sysemu/sysemu.h"
32 #include "qemu/error-report.h"
33 #include "qemu/sockets.h"
34 #include "qemu/timer.h"
35 #include "qemu/acl.h"
36 #include "qemu/config-file.h"
37 #include "qapi/qmp/qerror.h"
38 #include "qapi/qmp/types.h"
39 #include "qmp-commands.h"
40 #include "qemu/osdep.h"
41 #include "ui/input.h"
42 #include "qapi-event.h"
43 #include "crypto/hash.h"
44 #include "crypto/tlscredsanon.h"
45 #include "crypto/tlscredsx509.h"
46 #include "qom/object_interfaces.h"
48 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
49 #define VNC_REFRESH_INTERVAL_INC 50
50 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
51 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
52 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
54 #include "vnc_keysym.h"
55 #include "crypto/cipher.h"
57 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
58 QTAILQ_HEAD_INITIALIZER(vnc_displays);
60 static int vnc_cursor_define(VncState *vs);
61 static void vnc_release_modifiers(VncState *vs);
63 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
65 #ifdef _VNC_DEBUG
66 static const char *mn[] = {
67 [0] = "undefined",
68 [VNC_SHARE_MODE_CONNECTING] = "connecting",
69 [VNC_SHARE_MODE_SHARED] = "shared",
70 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
71 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
73 fprintf(stderr, "%s/%d: %s -> %s\n", __func__,
74 vs->csock, mn[vs->share_mode], mn[mode]);
75 #endif
77 switch (vs->share_mode) {
78 case VNC_SHARE_MODE_CONNECTING:
79 vs->vd->num_connecting--;
80 break;
81 case VNC_SHARE_MODE_SHARED:
82 vs->vd->num_shared--;
83 break;
84 case VNC_SHARE_MODE_EXCLUSIVE:
85 vs->vd->num_exclusive--;
86 break;
87 default:
88 break;
91 vs->share_mode = mode;
93 switch (vs->share_mode) {
94 case VNC_SHARE_MODE_CONNECTING:
95 vs->vd->num_connecting++;
96 break;
97 case VNC_SHARE_MODE_SHARED:
98 vs->vd->num_shared++;
99 break;
100 case VNC_SHARE_MODE_EXCLUSIVE:
101 vs->vd->num_exclusive++;
102 break;
103 default:
104 break;
108 static char *addr_to_string(const char *format,
109 struct sockaddr_storage *sa,
110 socklen_t salen) {
111 char *addr;
112 char host[NI_MAXHOST];
113 char serv[NI_MAXSERV];
114 int err;
115 size_t addrlen;
117 if ((err = getnameinfo((struct sockaddr *)sa, salen,
118 host, sizeof(host),
119 serv, sizeof(serv),
120 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
121 VNC_DEBUG("Cannot resolve address %d: %s\n",
122 err, gai_strerror(err));
123 return NULL;
126 /* Enough for the existing format + the 2 vars we're
127 * substituting in. */
128 addrlen = strlen(format) + strlen(host) + strlen(serv);
129 addr = g_malloc(addrlen + 1);
130 snprintf(addr, addrlen, format, host, serv);
131 addr[addrlen] = '\0';
133 return addr;
137 char *vnc_socket_local_addr(const char *format, int fd) {
138 struct sockaddr_storage sa;
139 socklen_t salen;
141 salen = sizeof(sa);
142 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
143 return NULL;
145 return addr_to_string(format, &sa, salen);
148 char *vnc_socket_remote_addr(const char *format, int fd) {
149 struct sockaddr_storage sa;
150 socklen_t salen;
152 salen = sizeof(sa);
153 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
154 return NULL;
156 return addr_to_string(format, &sa, salen);
159 static void vnc_init_basic_info(struct sockaddr_storage *sa,
160 socklen_t salen,
161 VncBasicInfo *info,
162 Error **errp)
164 char host[NI_MAXHOST];
165 char serv[NI_MAXSERV];
166 int err;
168 if ((err = getnameinfo((struct sockaddr *)sa, salen,
169 host, sizeof(host),
170 serv, sizeof(serv),
171 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
172 error_setg(errp, "Cannot resolve address: %s",
173 gai_strerror(err));
174 return;
177 info->host = g_strdup(host);
178 info->service = g_strdup(serv);
179 info->family = inet_netfamily(sa->ss_family);
182 static void vnc_init_basic_info_from_server_addr(int fd, VncBasicInfo *info,
183 Error **errp)
185 struct sockaddr_storage sa;
186 socklen_t salen;
188 salen = sizeof(sa);
189 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
190 error_setg_errno(errp, errno, "getsockname failed");
191 return;
194 vnc_init_basic_info(&sa, salen, info, errp);
197 static void vnc_init_basic_info_from_remote_addr(int fd, VncBasicInfo *info,
198 Error **errp)
200 struct sockaddr_storage sa;
201 socklen_t salen;
203 salen = sizeof(sa);
204 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
205 error_setg_errno(errp, errno, "getpeername failed");
206 return;
209 vnc_init_basic_info(&sa, salen, info, errp);
212 static const char *vnc_auth_name(VncDisplay *vd) {
213 switch (vd->auth) {
214 case VNC_AUTH_INVALID:
215 return "invalid";
216 case VNC_AUTH_NONE:
217 return "none";
218 case VNC_AUTH_VNC:
219 return "vnc";
220 case VNC_AUTH_RA2:
221 return "ra2";
222 case VNC_AUTH_RA2NE:
223 return "ra2ne";
224 case VNC_AUTH_TIGHT:
225 return "tight";
226 case VNC_AUTH_ULTRA:
227 return "ultra";
228 case VNC_AUTH_TLS:
229 return "tls";
230 case VNC_AUTH_VENCRYPT:
231 switch (vd->subauth) {
232 case VNC_AUTH_VENCRYPT_PLAIN:
233 return "vencrypt+plain";
234 case VNC_AUTH_VENCRYPT_TLSNONE:
235 return "vencrypt+tls+none";
236 case VNC_AUTH_VENCRYPT_TLSVNC:
237 return "vencrypt+tls+vnc";
238 case VNC_AUTH_VENCRYPT_TLSPLAIN:
239 return "vencrypt+tls+plain";
240 case VNC_AUTH_VENCRYPT_X509NONE:
241 return "vencrypt+x509+none";
242 case VNC_AUTH_VENCRYPT_X509VNC:
243 return "vencrypt+x509+vnc";
244 case VNC_AUTH_VENCRYPT_X509PLAIN:
245 return "vencrypt+x509+plain";
246 case VNC_AUTH_VENCRYPT_TLSSASL:
247 return "vencrypt+tls+sasl";
248 case VNC_AUTH_VENCRYPT_X509SASL:
249 return "vencrypt+x509+sasl";
250 default:
251 return "vencrypt";
253 case VNC_AUTH_SASL:
254 return "sasl";
256 return "unknown";
259 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
261 VncServerInfo *info;
262 Error *err = NULL;
264 info = g_malloc(sizeof(*info));
265 vnc_init_basic_info_from_server_addr(vd->lsock,
266 qapi_VncServerInfo_base(info), &err);
267 info->has_auth = true;
268 info->auth = g_strdup(vnc_auth_name(vd));
269 if (err) {
270 qapi_free_VncServerInfo(info);
271 info = NULL;
272 error_free(err);
274 return info;
277 static void vnc_client_cache_auth(VncState *client)
279 if (!client->info) {
280 return;
283 if (client->tls) {
284 client->info->x509_dname =
285 qcrypto_tls_session_get_peer_name(client->tls);
286 client->info->has_x509_dname =
287 client->info->x509_dname != NULL;
289 #ifdef CONFIG_VNC_SASL
290 if (client->sasl.conn &&
291 client->sasl.username) {
292 client->info->has_sasl_username = true;
293 client->info->sasl_username = g_strdup(client->sasl.username);
295 #endif
298 static void vnc_client_cache_addr(VncState *client)
300 Error *err = NULL;
302 client->info = g_malloc0(sizeof(*client->info));
303 vnc_init_basic_info_from_remote_addr(client->csock,
304 qapi_VncClientInfo_base(client->info),
305 &err);
306 if (err) {
307 qapi_free_VncClientInfo(client->info);
308 client->info = NULL;
309 error_free(err);
313 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
315 VncServerInfo *si;
317 if (!vs->info) {
318 return;
321 si = vnc_server_info_get(vs->vd);
322 if (!si) {
323 return;
326 switch (event) {
327 case QAPI_EVENT_VNC_CONNECTED:
328 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
329 &error_abort);
330 break;
331 case QAPI_EVENT_VNC_INITIALIZED:
332 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
333 break;
334 case QAPI_EVENT_VNC_DISCONNECTED:
335 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
336 break;
337 default:
338 break;
341 qapi_free_VncServerInfo(si);
344 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
346 struct sockaddr_storage sa;
347 socklen_t salen = sizeof(sa);
348 char host[NI_MAXHOST];
349 char serv[NI_MAXSERV];
350 VncClientInfo *info;
352 if (getpeername(client->csock, (struct sockaddr *)&sa, &salen) < 0) {
353 return NULL;
356 if (getnameinfo((struct sockaddr *)&sa, salen,
357 host, sizeof(host),
358 serv, sizeof(serv),
359 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
360 return NULL;
363 info = g_malloc0(sizeof(*info));
364 info->host = g_strdup(host);
365 info->service = g_strdup(serv);
366 info->family = inet_netfamily(sa.ss_family);
367 info->websocket = client->websocket;
369 if (client->tls) {
370 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
371 info->has_x509_dname = info->x509_dname != NULL;
373 #ifdef CONFIG_VNC_SASL
374 if (client->sasl.conn && client->sasl.username) {
375 info->has_sasl_username = true;
376 info->sasl_username = g_strdup(client->sasl.username);
378 #endif
380 return info;
383 static VncDisplay *vnc_display_find(const char *id)
385 VncDisplay *vd;
387 if (id == NULL) {
388 return QTAILQ_FIRST(&vnc_displays);
390 QTAILQ_FOREACH(vd, &vnc_displays, next) {
391 if (strcmp(id, vd->id) == 0) {
392 return vd;
395 return NULL;
398 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
400 VncClientInfoList *cinfo, *prev = NULL;
401 VncState *client;
403 QTAILQ_FOREACH(client, &vd->clients, next) {
404 cinfo = g_new0(VncClientInfoList, 1);
405 cinfo->value = qmp_query_vnc_client(client);
406 cinfo->next = prev;
407 prev = cinfo;
409 return prev;
412 VncInfo *qmp_query_vnc(Error **errp)
414 VncInfo *info = g_malloc0(sizeof(*info));
415 VncDisplay *vd = vnc_display_find(NULL);
417 if (vd == NULL || !vd->enabled) {
418 info->enabled = false;
419 } else {
420 struct sockaddr_storage sa;
421 socklen_t salen = sizeof(sa);
422 char host[NI_MAXHOST];
423 char serv[NI_MAXSERV];
425 info->enabled = true;
427 /* for compatibility with the original command */
428 info->has_clients = true;
429 info->clients = qmp_query_client_list(vd);
431 if (vd->lsock == -1) {
432 return info;
435 if (getsockname(vd->lsock, (struct sockaddr *)&sa,
436 &salen) == -1) {
437 error_setg(errp, QERR_UNDEFINED_ERROR);
438 goto out_error;
441 if (getnameinfo((struct sockaddr *)&sa, salen,
442 host, sizeof(host),
443 serv, sizeof(serv),
444 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
445 error_setg(errp, QERR_UNDEFINED_ERROR);
446 goto out_error;
449 info->has_host = true;
450 info->host = g_strdup(host);
452 info->has_service = true;
453 info->service = g_strdup(serv);
455 info->has_family = true;
456 info->family = inet_netfamily(sa.ss_family);
458 info->has_auth = true;
459 info->auth = g_strdup(vnc_auth_name(vd));
462 return info;
464 out_error:
465 qapi_free_VncInfo(info);
466 return NULL;
469 static VncBasicInfoList *qmp_query_server_entry(int socket,
470 bool websocket,
471 VncBasicInfoList *prev)
473 VncBasicInfoList *list;
474 VncBasicInfo *info;
475 struct sockaddr_storage sa;
476 socklen_t salen = sizeof(sa);
477 char host[NI_MAXHOST];
478 char serv[NI_MAXSERV];
480 if (getsockname(socket, (struct sockaddr *)&sa, &salen) < 0 ||
481 getnameinfo((struct sockaddr *)&sa, salen,
482 host, sizeof(host), serv, sizeof(serv),
483 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
484 return prev;
487 info = g_new0(VncBasicInfo, 1);
488 info->host = g_strdup(host);
489 info->service = g_strdup(serv);
490 info->family = inet_netfamily(sa.ss_family);
491 info->websocket = websocket;
493 list = g_new0(VncBasicInfoList, 1);
494 list->value = info;
495 list->next = prev;
496 return list;
499 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
501 switch (vd->auth) {
502 case VNC_AUTH_VNC:
503 info->auth = VNC_PRIMARY_AUTH_VNC;
504 break;
505 case VNC_AUTH_RA2:
506 info->auth = VNC_PRIMARY_AUTH_RA2;
507 break;
508 case VNC_AUTH_RA2NE:
509 info->auth = VNC_PRIMARY_AUTH_RA2NE;
510 break;
511 case VNC_AUTH_TIGHT:
512 info->auth = VNC_PRIMARY_AUTH_TIGHT;
513 break;
514 case VNC_AUTH_ULTRA:
515 info->auth = VNC_PRIMARY_AUTH_ULTRA;
516 break;
517 case VNC_AUTH_TLS:
518 info->auth = VNC_PRIMARY_AUTH_TLS;
519 break;
520 case VNC_AUTH_VENCRYPT:
521 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
522 info->has_vencrypt = true;
523 switch (vd->subauth) {
524 case VNC_AUTH_VENCRYPT_PLAIN:
525 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
526 break;
527 case VNC_AUTH_VENCRYPT_TLSNONE:
528 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
529 break;
530 case VNC_AUTH_VENCRYPT_TLSVNC:
531 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
532 break;
533 case VNC_AUTH_VENCRYPT_TLSPLAIN:
534 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
535 break;
536 case VNC_AUTH_VENCRYPT_X509NONE:
537 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
538 break;
539 case VNC_AUTH_VENCRYPT_X509VNC:
540 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
541 break;
542 case VNC_AUTH_VENCRYPT_X509PLAIN:
543 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
544 break;
545 case VNC_AUTH_VENCRYPT_TLSSASL:
546 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
547 break;
548 case VNC_AUTH_VENCRYPT_X509SASL:
549 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
550 break;
551 default:
552 info->has_vencrypt = false;
553 break;
555 break;
556 case VNC_AUTH_SASL:
557 info->auth = VNC_PRIMARY_AUTH_SASL;
558 break;
559 case VNC_AUTH_NONE:
560 default:
561 info->auth = VNC_PRIMARY_AUTH_NONE;
562 break;
566 VncInfo2List *qmp_query_vnc_servers(Error **errp)
568 VncInfo2List *item, *prev = NULL;
569 VncInfo2 *info;
570 VncDisplay *vd;
571 DeviceState *dev;
573 QTAILQ_FOREACH(vd, &vnc_displays, next) {
574 info = g_new0(VncInfo2, 1);
575 info->id = g_strdup(vd->id);
576 info->clients = qmp_query_client_list(vd);
577 qmp_query_auth(vd, info);
578 if (vd->dcl.con) {
579 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
580 "device", NULL));
581 info->has_display = true;
582 info->display = g_strdup(dev->id);
584 if (vd->lsock != -1) {
585 info->server = qmp_query_server_entry(vd->lsock, false,
586 info->server);
588 if (vd->lwebsock != -1) {
589 info->server = qmp_query_server_entry(vd->lwebsock, true,
590 info->server);
593 item = g_new0(VncInfo2List, 1);
594 item->value = info;
595 item->next = prev;
596 prev = item;
598 return prev;
601 /* TODO
602 1) Get the queue working for IO.
603 2) there is some weirdness when using the -S option (the screen is grey
604 and not totally invalidated
605 3) resolutions > 1024
608 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
609 static void vnc_disconnect_start(VncState *vs);
611 static void vnc_colordepth(VncState *vs);
612 static void framebuffer_update_request(VncState *vs, int incremental,
613 int x_position, int y_position,
614 int w, int h);
615 static void vnc_refresh(DisplayChangeListener *dcl);
616 static int vnc_refresh_server_surface(VncDisplay *vd);
618 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
619 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
620 int width, int height,
621 int x, int y, int w, int h) {
622 /* this is needed this to ensure we updated all affected
623 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
624 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
625 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
627 x = MIN(x, width);
628 y = MIN(y, height);
629 w = MIN(x + w, width) - x;
630 h = MIN(y + h, height);
632 for (; y < h; y++) {
633 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
634 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
638 static void vnc_dpy_update(DisplayChangeListener *dcl,
639 int x, int y, int w, int h)
641 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
642 struct VncSurface *s = &vd->guest;
643 int width = pixman_image_get_width(vd->server);
644 int height = pixman_image_get_height(vd->server);
646 vnc_set_area_dirty(s->dirty, width, height, x, y, w, h);
649 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
650 int32_t encoding)
652 vnc_write_u16(vs, x);
653 vnc_write_u16(vs, y);
654 vnc_write_u16(vs, w);
655 vnc_write_u16(vs, h);
657 vnc_write_s32(vs, encoding);
661 static void vnc_desktop_resize(VncState *vs)
663 if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
664 return;
666 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
667 vs->client_height == pixman_image_get_height(vs->vd->server)) {
668 return;
670 vs->client_width = pixman_image_get_width(vs->vd->server);
671 vs->client_height = pixman_image_get_height(vs->vd->server);
672 vnc_lock_output(vs);
673 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
674 vnc_write_u8(vs, 0);
675 vnc_write_u16(vs, 1); /* number of rects */
676 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
677 VNC_ENCODING_DESKTOPRESIZE);
678 vnc_unlock_output(vs);
679 vnc_flush(vs);
682 static void vnc_abort_display_jobs(VncDisplay *vd)
684 VncState *vs;
686 QTAILQ_FOREACH(vs, &vd->clients, next) {
687 vnc_lock_output(vs);
688 vs->abort = true;
689 vnc_unlock_output(vs);
691 QTAILQ_FOREACH(vs, &vd->clients, next) {
692 vnc_jobs_join(vs);
694 QTAILQ_FOREACH(vs, &vd->clients, next) {
695 vnc_lock_output(vs);
696 vs->abort = false;
697 vnc_unlock_output(vs);
701 int vnc_server_fb_stride(VncDisplay *vd)
703 return pixman_image_get_stride(vd->server);
706 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
708 uint8_t *ptr;
710 ptr = (uint8_t *)pixman_image_get_data(vd->server);
711 ptr += y * vnc_server_fb_stride(vd);
712 ptr += x * VNC_SERVER_FB_BYTES;
713 return ptr;
716 static void vnc_dpy_switch(DisplayChangeListener *dcl,
717 DisplaySurface *surface)
719 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
720 VncState *vs;
721 int width, height;
723 vnc_abort_display_jobs(vd);
725 /* server surface */
726 qemu_pixman_image_unref(vd->server);
727 vd->ds = surface;
728 width = MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
729 VNC_DIRTY_PIXELS_PER_BIT));
730 height = MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
731 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
732 width, height, NULL, 0);
734 /* guest surface */
735 #if 0 /* FIXME */
736 if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
737 console_color_init(ds);
738 #endif
739 qemu_pixman_image_unref(vd->guest.fb);
740 vd->guest.fb = pixman_image_ref(surface->image);
741 vd->guest.format = surface->format;
742 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
743 vnc_set_area_dirty(vd->guest.dirty, width, height, 0, 0,
744 width, height);
746 QTAILQ_FOREACH(vs, &vd->clients, next) {
747 vnc_colordepth(vs);
748 vnc_desktop_resize(vs);
749 if (vs->vd->cursor) {
750 vnc_cursor_define(vs);
752 memset(vs->dirty, 0x00, sizeof(vs->dirty));
753 vnc_set_area_dirty(vs->dirty, width, height, 0, 0,
754 width, height);
758 /* fastest code */
759 static void vnc_write_pixels_copy(VncState *vs,
760 void *pixels, int size)
762 vnc_write(vs, pixels, size);
765 /* slowest but generic code. */
766 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
768 uint8_t r, g, b;
770 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
771 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
772 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
773 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
774 #else
775 # error need some bits here if you change VNC_SERVER_FB_FORMAT
776 #endif
777 v = (r << vs->client_pf.rshift) |
778 (g << vs->client_pf.gshift) |
779 (b << vs->client_pf.bshift);
780 switch (vs->client_pf.bytes_per_pixel) {
781 case 1:
782 buf[0] = v;
783 break;
784 case 2:
785 if (vs->client_be) {
786 buf[0] = v >> 8;
787 buf[1] = v;
788 } else {
789 buf[1] = v >> 8;
790 buf[0] = v;
792 break;
793 default:
794 case 4:
795 if (vs->client_be) {
796 buf[0] = v >> 24;
797 buf[1] = v >> 16;
798 buf[2] = v >> 8;
799 buf[3] = v;
800 } else {
801 buf[3] = v >> 24;
802 buf[2] = v >> 16;
803 buf[1] = v >> 8;
804 buf[0] = v;
806 break;
810 static void vnc_write_pixels_generic(VncState *vs,
811 void *pixels1, int size)
813 uint8_t buf[4];
815 if (VNC_SERVER_FB_BYTES == 4) {
816 uint32_t *pixels = pixels1;
817 int n, i;
818 n = size >> 2;
819 for (i = 0; i < n; i++) {
820 vnc_convert_pixel(vs, buf, pixels[i]);
821 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
826 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
828 int i;
829 uint8_t *row;
830 VncDisplay *vd = vs->vd;
832 row = vnc_server_fb_ptr(vd, x, y);
833 for (i = 0; i < h; i++) {
834 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
835 row += vnc_server_fb_stride(vd);
837 return 1;
840 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
842 int n = 0;
843 bool encode_raw = false;
844 size_t saved_offs = vs->output.offset;
846 switch(vs->vnc_encoding) {
847 case VNC_ENCODING_ZLIB:
848 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
849 break;
850 case VNC_ENCODING_HEXTILE:
851 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
852 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
853 break;
854 case VNC_ENCODING_TIGHT:
855 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
856 break;
857 case VNC_ENCODING_TIGHT_PNG:
858 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
859 break;
860 case VNC_ENCODING_ZRLE:
861 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
862 break;
863 case VNC_ENCODING_ZYWRLE:
864 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
865 break;
866 default:
867 encode_raw = true;
868 break;
871 /* If the client has the same pixel format as our internal buffer and
872 * a RAW encoding would need less space fall back to RAW encoding to
873 * save bandwidth and processing power in the client. */
874 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
875 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
876 vs->output.offset = saved_offs;
877 encode_raw = true;
880 if (encode_raw) {
881 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
882 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
885 return n;
888 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
890 /* send bitblit op to the vnc client */
891 vnc_lock_output(vs);
892 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
893 vnc_write_u8(vs, 0);
894 vnc_write_u16(vs, 1); /* number of rects */
895 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
896 vnc_write_u16(vs, src_x);
897 vnc_write_u16(vs, src_y);
898 vnc_unlock_output(vs);
899 vnc_flush(vs);
902 static void vnc_dpy_copy(DisplayChangeListener *dcl,
903 int src_x, int src_y,
904 int dst_x, int dst_y, int w, int h)
906 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
907 VncState *vs, *vn;
908 uint8_t *src_row;
909 uint8_t *dst_row;
910 int i, x, y, pitch, inc, w_lim, s;
911 int cmp_bytes;
913 vnc_refresh_server_surface(vd);
914 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
915 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
916 vs->force_update = 1;
917 vnc_update_client(vs, 1, true);
918 /* vs might be free()ed here */
922 /* do bitblit op on the local surface too */
923 pitch = vnc_server_fb_stride(vd);
924 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
925 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
926 y = dst_y;
927 inc = 1;
928 if (dst_y > src_y) {
929 /* copy backwards */
930 src_row += pitch * (h-1);
931 dst_row += pitch * (h-1);
932 pitch = -pitch;
933 y = dst_y + h - 1;
934 inc = -1;
936 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
937 if (w_lim < 0) {
938 w_lim = w;
939 } else {
940 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
942 for (i = 0; i < h; i++) {
943 for (x = 0; x <= w_lim;
944 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
945 if (x == w_lim) {
946 if ((s = w - w_lim) == 0)
947 break;
948 } else if (!x) {
949 s = (VNC_DIRTY_PIXELS_PER_BIT -
950 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
951 s = MIN(s, w_lim);
952 } else {
953 s = VNC_DIRTY_PIXELS_PER_BIT;
955 cmp_bytes = s * VNC_SERVER_FB_BYTES;
956 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
957 continue;
958 memmove(dst_row, src_row, cmp_bytes);
959 QTAILQ_FOREACH(vs, &vd->clients, next) {
960 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
961 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
962 vs->dirty[y]);
966 src_row += pitch - w * VNC_SERVER_FB_BYTES;
967 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
968 y += inc;
971 QTAILQ_FOREACH(vs, &vd->clients, next) {
972 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
973 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
978 static void vnc_mouse_set(DisplayChangeListener *dcl,
979 int x, int y, int visible)
981 /* can we ask the client(s) to move the pointer ??? */
984 static int vnc_cursor_define(VncState *vs)
986 QEMUCursor *c = vs->vd->cursor;
987 int isize;
989 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
990 vnc_lock_output(vs);
991 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
992 vnc_write_u8(vs, 0); /* padding */
993 vnc_write_u16(vs, 1); /* # of rects */
994 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
995 VNC_ENCODING_RICH_CURSOR);
996 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
997 vnc_write_pixels_generic(vs, c->data, isize);
998 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
999 vnc_unlock_output(vs);
1000 return 0;
1002 return -1;
1005 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1006 QEMUCursor *c)
1008 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1009 VncState *vs;
1011 cursor_put(vd->cursor);
1012 g_free(vd->cursor_mask);
1014 vd->cursor = c;
1015 cursor_get(vd->cursor);
1016 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1017 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1018 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1020 QTAILQ_FOREACH(vs, &vd->clients, next) {
1021 vnc_cursor_define(vs);
1025 static int find_and_clear_dirty_height(VncState *vs,
1026 int y, int last_x, int x, int height)
1028 int h;
1030 for (h = 1; h < (height - y); h++) {
1031 if (!test_bit(last_x, vs->dirty[y + h])) {
1032 break;
1034 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1037 return h;
1040 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1042 vs->has_dirty += has_dirty;
1043 if (vs->need_update && vs->csock != -1) {
1044 VncDisplay *vd = vs->vd;
1045 VncJob *job;
1046 int y;
1047 int height, width;
1048 int n = 0;
1050 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1051 /* kernel send buffers are full -> drop frames to throttle */
1052 return 0;
1054 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1055 return 0;
1058 * Send screen updates to the vnc client using the server
1059 * surface and server dirty map. guest surface updates
1060 * happening in parallel don't disturb us, the next pass will
1061 * send them to the client.
1063 job = vnc_job_new(vs);
1065 height = pixman_image_get_height(vd->server);
1066 width = pixman_image_get_width(vd->server);
1068 y = 0;
1069 for (;;) {
1070 int x, h;
1071 unsigned long x2;
1072 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1073 height * VNC_DIRTY_BPL(vs),
1074 y * VNC_DIRTY_BPL(vs));
1075 if (offset == height * VNC_DIRTY_BPL(vs)) {
1076 /* no more dirty bits */
1077 break;
1079 y = offset / VNC_DIRTY_BPL(vs);
1080 x = offset % VNC_DIRTY_BPL(vs);
1081 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1082 VNC_DIRTY_BPL(vs), x);
1083 bitmap_clear(vs->dirty[y], x, x2 - x);
1084 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1085 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1086 if (x2 > x) {
1087 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1088 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1090 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1091 y += h;
1092 if (y == height) {
1093 break;
1098 vnc_job_push(job);
1099 if (sync) {
1100 vnc_jobs_join(vs);
1102 vs->force_update = 0;
1103 vs->has_dirty = 0;
1104 return n;
1107 if (vs->csock == -1) {
1108 vnc_disconnect_finish(vs);
1109 } else if (sync) {
1110 vnc_jobs_join(vs);
1113 return 0;
1116 /* audio */
1117 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1119 VncState *vs = opaque;
1121 switch (cmd) {
1122 case AUD_CNOTIFY_DISABLE:
1123 vnc_lock_output(vs);
1124 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1125 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1126 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1127 vnc_unlock_output(vs);
1128 vnc_flush(vs);
1129 break;
1131 case AUD_CNOTIFY_ENABLE:
1132 vnc_lock_output(vs);
1133 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1134 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1135 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1136 vnc_unlock_output(vs);
1137 vnc_flush(vs);
1138 break;
1142 static void audio_capture_destroy(void *opaque)
1146 static void audio_capture(void *opaque, void *buf, int size)
1148 VncState *vs = opaque;
1150 vnc_lock_output(vs);
1151 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1152 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1153 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1154 vnc_write_u32(vs, size);
1155 vnc_write(vs, buf, size);
1156 vnc_unlock_output(vs);
1157 vnc_flush(vs);
1160 static void audio_add(VncState *vs)
1162 struct audio_capture_ops ops;
1164 if (vs->audio_cap) {
1165 error_report("audio already running");
1166 return;
1169 ops.notify = audio_capture_notify;
1170 ops.destroy = audio_capture_destroy;
1171 ops.capture = audio_capture;
1173 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1174 if (!vs->audio_cap) {
1175 error_report("Failed to add audio capture");
1179 static void audio_del(VncState *vs)
1181 if (vs->audio_cap) {
1182 AUD_del_capture(vs->audio_cap, vs);
1183 vs->audio_cap = NULL;
1187 static void vnc_disconnect_start(VncState *vs)
1189 if (vs->csock == -1)
1190 return;
1191 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1192 qemu_set_fd_handler(vs->csock, NULL, NULL, NULL);
1193 closesocket(vs->csock);
1194 vs->csock = -1;
1197 void vnc_disconnect_finish(VncState *vs)
1199 int i;
1201 vnc_jobs_join(vs); /* Wait encoding jobs */
1203 vnc_lock_output(vs);
1204 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1206 buffer_free(&vs->input);
1207 buffer_free(&vs->output);
1208 buffer_free(&vs->ws_input);
1209 buffer_free(&vs->ws_output);
1211 qapi_free_VncClientInfo(vs->info);
1213 vnc_zlib_clear(vs);
1214 vnc_tight_clear(vs);
1215 vnc_zrle_clear(vs);
1217 qcrypto_tls_session_free(vs->tls);
1218 #ifdef CONFIG_VNC_SASL
1219 vnc_sasl_client_cleanup(vs);
1220 #endif /* CONFIG_VNC_SASL */
1221 audio_del(vs);
1222 vnc_release_modifiers(vs);
1224 if (vs->initialized) {
1225 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1226 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1229 if (vs->vd->lock_key_sync)
1230 qemu_remove_led_event_handler(vs->led);
1231 vnc_unlock_output(vs);
1233 qemu_mutex_destroy(&vs->output_mutex);
1234 if (vs->bh != NULL) {
1235 qemu_bh_delete(vs->bh);
1237 buffer_free(&vs->jobs_buffer);
1239 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1240 g_free(vs->lossy_rect[i]);
1242 g_free(vs->lossy_rect);
1243 g_free(vs);
1246 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, int last_errno)
1248 if (ret == 0 || ret == -1) {
1249 if (ret == -1) {
1250 switch (last_errno) {
1251 case EINTR:
1252 case EAGAIN:
1253 #ifdef _WIN32
1254 case WSAEWOULDBLOCK:
1255 #endif
1256 return 0;
1257 default:
1258 break;
1262 VNC_DEBUG("Closing down client sock: ret %zd, errno %d\n",
1263 ret, ret < 0 ? last_errno : 0);
1264 vnc_disconnect_start(vs);
1266 return 0;
1268 return ret;
1272 void vnc_client_error(VncState *vs)
1274 VNC_DEBUG("Closing down client sock: protocol error\n");
1275 vnc_disconnect_start(vs);
1279 ssize_t vnc_tls_pull(char *buf, size_t len, void *opaque)
1281 VncState *vs = opaque;
1282 ssize_t ret;
1284 retry:
1285 ret = qemu_recv(vs->csock, buf, len, 0);
1286 if (ret < 0) {
1287 if (errno == EINTR) {
1288 goto retry;
1290 return -1;
1292 return ret;
1296 ssize_t vnc_tls_push(const char *buf, size_t len, void *opaque)
1298 VncState *vs = opaque;
1299 ssize_t ret;
1301 retry:
1302 ret = send(vs->csock, buf, len, 0);
1303 if (ret < 0) {
1304 if (errno == EINTR) {
1305 goto retry;
1307 return -1;
1309 return ret;
1314 * Called to write a chunk of data to the client socket. The data may
1315 * be the raw data, or may have already been encoded by SASL.
1316 * The data will be written either straight onto the socket, or
1317 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1319 * NB, it is theoretically possible to have 2 layers of encryption,
1320 * both SASL, and this TLS layer. It is highly unlikely in practice
1321 * though, since SASL encryption will typically be a no-op if TLS
1322 * is active
1324 * Returns the number of bytes written, which may be less than
1325 * the requested 'datalen' if the socket would block. Returns
1326 * -1 on error, and disconnects the client socket.
1328 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1330 ssize_t ret;
1331 int err = 0;
1332 if (vs->tls) {
1333 ret = qcrypto_tls_session_write(vs->tls, (const char *)data, datalen);
1334 if (ret < 0) {
1335 err = errno;
1337 } else {
1338 ret = send(vs->csock, (const void *)data, datalen, 0);
1339 if (ret < 0) {
1340 err = socket_error();
1343 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1344 return vnc_client_io_error(vs, ret, err);
1349 * Called to write buffered data to the client socket, when not
1350 * using any SASL SSF encryption layers. Will write as much data
1351 * as possible without blocking. If all buffered data is written,
1352 * will switch the FD poll() handler back to read monitoring.
1354 * Returns the number of bytes written, which may be less than
1355 * the buffered output data if the socket would block. Returns
1356 * -1 on error, and disconnects the client socket.
1358 static ssize_t vnc_client_write_plain(VncState *vs)
1360 ssize_t ret;
1362 #ifdef CONFIG_VNC_SASL
1363 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1364 vs->output.buffer, vs->output.capacity, vs->output.offset,
1365 vs->sasl.waitWriteSSF);
1367 if (vs->sasl.conn &&
1368 vs->sasl.runSSF &&
1369 vs->sasl.waitWriteSSF) {
1370 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1371 if (ret)
1372 vs->sasl.waitWriteSSF -= ret;
1373 } else
1374 #endif /* CONFIG_VNC_SASL */
1375 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1376 if (!ret)
1377 return 0;
1379 buffer_advance(&vs->output, ret);
1381 if (vs->output.offset == 0) {
1382 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
1385 return ret;
1390 * First function called whenever there is data to be written to
1391 * the client socket. Will delegate actual work according to whether
1392 * SASL SSF layers are enabled (thus requiring encryption calls)
1394 static void vnc_client_write_locked(void *opaque)
1396 VncState *vs = opaque;
1398 #ifdef CONFIG_VNC_SASL
1399 if (vs->sasl.conn &&
1400 vs->sasl.runSSF &&
1401 !vs->sasl.waitWriteSSF) {
1402 vnc_client_write_sasl(vs);
1403 } else
1404 #endif /* CONFIG_VNC_SASL */
1406 if (vs->encode_ws) {
1407 vnc_client_write_ws(vs);
1408 } else {
1409 vnc_client_write_plain(vs);
1414 void vnc_client_write(void *opaque)
1416 VncState *vs = opaque;
1418 vnc_lock_output(vs);
1419 if (vs->output.offset || vs->ws_output.offset) {
1420 vnc_client_write_locked(opaque);
1421 } else if (vs->csock != -1) {
1422 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
1424 vnc_unlock_output(vs);
1427 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1429 vs->read_handler = func;
1430 vs->read_handler_expect = expecting;
1435 * Called to read a chunk of data from the client socket. The data may
1436 * be the raw data, or may need to be further decoded by SASL.
1437 * The data will be read either straight from to the socket, or
1438 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1440 * NB, it is theoretically possible to have 2 layers of encryption,
1441 * both SASL, and this TLS layer. It is highly unlikely in practice
1442 * though, since SASL encryption will typically be a no-op if TLS
1443 * is active
1445 * Returns the number of bytes read, which may be less than
1446 * the requested 'datalen' if the socket would block. Returns
1447 * -1 on error, and disconnects the client socket.
1449 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1451 ssize_t ret;
1452 int err = -1;
1453 if (vs->tls) {
1454 ret = qcrypto_tls_session_read(vs->tls, (char *)data, datalen);
1455 if (ret < 0) {
1456 err = errno;
1458 } else {
1459 ret = qemu_recv(vs->csock, data, datalen, 0);
1460 if (ret < 0) {
1461 err = socket_error();
1464 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1465 return vnc_client_io_error(vs, ret, err);
1470 * Called to read data from the client socket to the input buffer,
1471 * when not using any SASL SSF encryption layers. Will read as much
1472 * data as possible without blocking.
1474 * Returns the number of bytes read. Returns -1 on error, and
1475 * disconnects the client socket.
1477 static ssize_t vnc_client_read_plain(VncState *vs)
1479 ssize_t ret;
1480 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1481 vs->input.buffer, vs->input.capacity, vs->input.offset);
1482 buffer_reserve(&vs->input, 4096);
1483 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1484 if (!ret)
1485 return 0;
1486 vs->input.offset += ret;
1487 return ret;
1490 static void vnc_jobs_bh(void *opaque)
1492 VncState *vs = opaque;
1494 vnc_jobs_consume_buffer(vs);
1498 * First function called whenever there is more data to be read from
1499 * the client socket. Will delegate actual work according to whether
1500 * SASL SSF layers are enabled (thus requiring decryption calls)
1502 void vnc_client_read(void *opaque)
1504 VncState *vs = opaque;
1505 ssize_t ret;
1507 #ifdef CONFIG_VNC_SASL
1508 if (vs->sasl.conn && vs->sasl.runSSF)
1509 ret = vnc_client_read_sasl(vs);
1510 else
1511 #endif /* CONFIG_VNC_SASL */
1512 if (vs->encode_ws) {
1513 ret = vnc_client_read_ws(vs);
1514 if (ret == -1) {
1515 vnc_disconnect_start(vs);
1516 return;
1517 } else if (ret == -2) {
1518 vnc_client_error(vs);
1519 return;
1521 } else {
1522 ret = vnc_client_read_plain(vs);
1524 if (!ret) {
1525 if (vs->csock == -1)
1526 vnc_disconnect_finish(vs);
1527 return;
1530 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1531 size_t len = vs->read_handler_expect;
1532 int ret;
1534 ret = vs->read_handler(vs, vs->input.buffer, len);
1535 if (vs->csock == -1) {
1536 vnc_disconnect_finish(vs);
1537 return;
1540 if (!ret) {
1541 buffer_advance(&vs->input, len);
1542 } else {
1543 vs->read_handler_expect = ret;
1548 void vnc_write(VncState *vs, const void *data, size_t len)
1550 buffer_reserve(&vs->output, len);
1552 if (vs->csock != -1 && buffer_empty(&vs->output)) {
1553 qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs);
1556 buffer_append(&vs->output, data, len);
1559 void vnc_write_s32(VncState *vs, int32_t value)
1561 vnc_write_u32(vs, *(uint32_t *)&value);
1564 void vnc_write_u32(VncState *vs, uint32_t value)
1566 uint8_t buf[4];
1568 buf[0] = (value >> 24) & 0xFF;
1569 buf[1] = (value >> 16) & 0xFF;
1570 buf[2] = (value >> 8) & 0xFF;
1571 buf[3] = value & 0xFF;
1573 vnc_write(vs, buf, 4);
1576 void vnc_write_u16(VncState *vs, uint16_t value)
1578 uint8_t buf[2];
1580 buf[0] = (value >> 8) & 0xFF;
1581 buf[1] = value & 0xFF;
1583 vnc_write(vs, buf, 2);
1586 void vnc_write_u8(VncState *vs, uint8_t value)
1588 vnc_write(vs, (char *)&value, 1);
1591 void vnc_flush(VncState *vs)
1593 vnc_lock_output(vs);
1594 if (vs->csock != -1 && (vs->output.offset ||
1595 vs->ws_output.offset)) {
1596 vnc_client_write_locked(vs);
1598 vnc_unlock_output(vs);
1601 static uint8_t read_u8(uint8_t *data, size_t offset)
1603 return data[offset];
1606 static uint16_t read_u16(uint8_t *data, size_t offset)
1608 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1611 static int32_t read_s32(uint8_t *data, size_t offset)
1613 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1614 (data[offset + 2] << 8) | data[offset + 3]);
1617 uint32_t read_u32(uint8_t *data, size_t offset)
1619 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1620 (data[offset + 2] << 8) | data[offset + 3]);
1623 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1627 static void check_pointer_type_change(Notifier *notifier, void *data)
1629 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1630 int absolute = qemu_input_is_absolute();
1632 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1633 vnc_lock_output(vs);
1634 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1635 vnc_write_u8(vs, 0);
1636 vnc_write_u16(vs, 1);
1637 vnc_framebuffer_update(vs, absolute, 0,
1638 pixman_image_get_width(vs->vd->server),
1639 pixman_image_get_height(vs->vd->server),
1640 VNC_ENCODING_POINTER_TYPE_CHANGE);
1641 vnc_unlock_output(vs);
1642 vnc_flush(vs);
1644 vs->absolute = absolute;
1647 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1649 static uint32_t bmap[INPUT_BUTTON_MAX] = {
1650 [INPUT_BUTTON_LEFT] = 0x01,
1651 [INPUT_BUTTON_MIDDLE] = 0x02,
1652 [INPUT_BUTTON_RIGHT] = 0x04,
1653 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1654 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1656 QemuConsole *con = vs->vd->dcl.con;
1657 int width = pixman_image_get_width(vs->vd->server);
1658 int height = pixman_image_get_height(vs->vd->server);
1660 if (vs->last_bmask != button_mask) {
1661 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1662 vs->last_bmask = button_mask;
1665 if (vs->absolute) {
1666 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1667 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1668 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1669 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1670 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1671 } else {
1672 if (vs->last_x != -1) {
1673 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1674 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1676 vs->last_x = x;
1677 vs->last_y = y;
1679 qemu_input_event_sync();
1682 static void reset_keys(VncState *vs)
1684 int i;
1685 for(i = 0; i < 256; i++) {
1686 if (vs->modifiers_state[i]) {
1687 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1688 vs->modifiers_state[i] = 0;
1693 static void press_key(VncState *vs, int keysym)
1695 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1696 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1697 qemu_input_event_send_key_delay(0);
1698 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1699 qemu_input_event_send_key_delay(0);
1702 static int current_led_state(VncState *vs)
1704 int ledstate = 0;
1706 if (vs->modifiers_state[0x46]) {
1707 ledstate |= QEMU_SCROLL_LOCK_LED;
1709 if (vs->modifiers_state[0x45]) {
1710 ledstate |= QEMU_NUM_LOCK_LED;
1712 if (vs->modifiers_state[0x3a]) {
1713 ledstate |= QEMU_CAPS_LOCK_LED;
1716 return ledstate;
1719 static void vnc_led_state_change(VncState *vs)
1721 int ledstate = 0;
1723 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1724 return;
1727 ledstate = current_led_state(vs);
1728 vnc_lock_output(vs);
1729 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1730 vnc_write_u8(vs, 0);
1731 vnc_write_u16(vs, 1);
1732 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1733 vnc_write_u8(vs, ledstate);
1734 vnc_unlock_output(vs);
1735 vnc_flush(vs);
1738 static void kbd_leds(void *opaque, int ledstate)
1740 VncState *vs = opaque;
1741 int caps, num, scr;
1742 bool has_changed = (ledstate != current_led_state(vs));
1744 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1745 (ledstate & QEMU_NUM_LOCK_LED),
1746 (ledstate & QEMU_SCROLL_LOCK_LED));
1748 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1749 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1750 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1752 if (vs->modifiers_state[0x3a] != caps) {
1753 vs->modifiers_state[0x3a] = caps;
1755 if (vs->modifiers_state[0x45] != num) {
1756 vs->modifiers_state[0x45] = num;
1758 if (vs->modifiers_state[0x46] != scr) {
1759 vs->modifiers_state[0x46] = scr;
1762 /* Sending the current led state message to the client */
1763 if (has_changed) {
1764 vnc_led_state_change(vs);
1768 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1770 /* QEMU console switch */
1771 switch(keycode) {
1772 case 0x2a: /* Left Shift */
1773 case 0x36: /* Right Shift */
1774 case 0x1d: /* Left CTRL */
1775 case 0x9d: /* Right CTRL */
1776 case 0x38: /* Left ALT */
1777 case 0xb8: /* Right ALT */
1778 if (down)
1779 vs->modifiers_state[keycode] = 1;
1780 else
1781 vs->modifiers_state[keycode] = 0;
1782 break;
1783 case 0x02 ... 0x0a: /* '1' to '9' keys */
1784 if (vs->vd->dcl.con == NULL &&
1785 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1786 /* Reset the modifiers sent to the current console */
1787 reset_keys(vs);
1788 console_select(keycode - 0x02);
1789 return;
1791 break;
1792 case 0x3a: /* CapsLock */
1793 case 0x45: /* NumLock */
1794 if (down)
1795 vs->modifiers_state[keycode] ^= 1;
1796 break;
1799 /* Turn off the lock state sync logic if the client support the led
1800 state extension.
1802 if (down && vs->vd->lock_key_sync &&
1803 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1804 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1805 /* If the numlock state needs to change then simulate an additional
1806 keypress before sending this one. This will happen if the user
1807 toggles numlock away from the VNC window.
1809 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1810 if (!vs->modifiers_state[0x45]) {
1811 trace_vnc_key_sync_numlock(true);
1812 vs->modifiers_state[0x45] = 1;
1813 press_key(vs, 0xff7f);
1815 } else {
1816 if (vs->modifiers_state[0x45]) {
1817 trace_vnc_key_sync_numlock(false);
1818 vs->modifiers_state[0x45] = 0;
1819 press_key(vs, 0xff7f);
1824 if (down && vs->vd->lock_key_sync &&
1825 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1826 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1827 /* If the capslock state needs to change then simulate an additional
1828 keypress before sending this one. This will happen if the user
1829 toggles capslock away from the VNC window.
1831 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1832 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1833 int capslock = !!(vs->modifiers_state[0x3a]);
1834 if (capslock) {
1835 if (uppercase == shift) {
1836 trace_vnc_key_sync_capslock(false);
1837 vs->modifiers_state[0x3a] = 0;
1838 press_key(vs, 0xffe5);
1840 } else {
1841 if (uppercase != shift) {
1842 trace_vnc_key_sync_capslock(true);
1843 vs->modifiers_state[0x3a] = 1;
1844 press_key(vs, 0xffe5);
1849 if (qemu_console_is_graphic(NULL)) {
1850 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1851 } else {
1852 bool numlock = vs->modifiers_state[0x45];
1853 bool control = (vs->modifiers_state[0x1d] ||
1854 vs->modifiers_state[0x9d]);
1855 /* QEMU console emulation */
1856 if (down) {
1857 switch (keycode) {
1858 case 0x2a: /* Left Shift */
1859 case 0x36: /* Right Shift */
1860 case 0x1d: /* Left CTRL */
1861 case 0x9d: /* Right CTRL */
1862 case 0x38: /* Left ALT */
1863 case 0xb8: /* Right ALT */
1864 break;
1865 case 0xc8:
1866 kbd_put_keysym(QEMU_KEY_UP);
1867 break;
1868 case 0xd0:
1869 kbd_put_keysym(QEMU_KEY_DOWN);
1870 break;
1871 case 0xcb:
1872 kbd_put_keysym(QEMU_KEY_LEFT);
1873 break;
1874 case 0xcd:
1875 kbd_put_keysym(QEMU_KEY_RIGHT);
1876 break;
1877 case 0xd3:
1878 kbd_put_keysym(QEMU_KEY_DELETE);
1879 break;
1880 case 0xc7:
1881 kbd_put_keysym(QEMU_KEY_HOME);
1882 break;
1883 case 0xcf:
1884 kbd_put_keysym(QEMU_KEY_END);
1885 break;
1886 case 0xc9:
1887 kbd_put_keysym(QEMU_KEY_PAGEUP);
1888 break;
1889 case 0xd1:
1890 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1891 break;
1893 case 0x47:
1894 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1895 break;
1896 case 0x48:
1897 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1898 break;
1899 case 0x49:
1900 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1901 break;
1902 case 0x4b:
1903 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1904 break;
1905 case 0x4c:
1906 kbd_put_keysym('5');
1907 break;
1908 case 0x4d:
1909 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1910 break;
1911 case 0x4f:
1912 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1913 break;
1914 case 0x50:
1915 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1916 break;
1917 case 0x51:
1918 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1919 break;
1920 case 0x52:
1921 kbd_put_keysym('0');
1922 break;
1923 case 0x53:
1924 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1925 break;
1927 case 0xb5:
1928 kbd_put_keysym('/');
1929 break;
1930 case 0x37:
1931 kbd_put_keysym('*');
1932 break;
1933 case 0x4a:
1934 kbd_put_keysym('-');
1935 break;
1936 case 0x4e:
1937 kbd_put_keysym('+');
1938 break;
1939 case 0x9c:
1940 kbd_put_keysym('\n');
1941 break;
1943 default:
1944 if (control) {
1945 kbd_put_keysym(sym & 0x1f);
1946 } else {
1947 kbd_put_keysym(sym);
1949 break;
1955 static void vnc_release_modifiers(VncState *vs)
1957 static const int keycodes[] = {
1958 /* shift, control, alt keys, both left & right */
1959 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1961 int i, keycode;
1963 if (!qemu_console_is_graphic(NULL)) {
1964 return;
1966 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1967 keycode = keycodes[i];
1968 if (!vs->modifiers_state[keycode]) {
1969 continue;
1971 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1975 static const char *code2name(int keycode)
1977 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1980 static void key_event(VncState *vs, int down, uint32_t sym)
1982 int keycode;
1983 int lsym = sym;
1985 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
1986 lsym = lsym - 'A' + 'a';
1989 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
1990 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
1991 do_key_event(vs, down, keycode, sym);
1994 static void ext_key_event(VncState *vs, int down,
1995 uint32_t sym, uint16_t keycode)
1997 /* if the user specifies a keyboard layout, always use it */
1998 if (keyboard_layout) {
1999 key_event(vs, down, sym);
2000 } else {
2001 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2002 do_key_event(vs, down, keycode, sym);
2006 static void framebuffer_update_request(VncState *vs, int incremental,
2007 int x, int y, int w, int h)
2009 int width = pixman_image_get_width(vs->vd->server);
2010 int height = pixman_image_get_height(vs->vd->server);
2012 vs->need_update = 1;
2014 if (incremental) {
2015 return;
2018 vs->force_update = 1;
2019 vnc_set_area_dirty(vs->dirty, width, height, x, y, w, h);
2022 static void send_ext_key_event_ack(VncState *vs)
2024 vnc_lock_output(vs);
2025 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2026 vnc_write_u8(vs, 0);
2027 vnc_write_u16(vs, 1);
2028 vnc_framebuffer_update(vs, 0, 0,
2029 pixman_image_get_width(vs->vd->server),
2030 pixman_image_get_height(vs->vd->server),
2031 VNC_ENCODING_EXT_KEY_EVENT);
2032 vnc_unlock_output(vs);
2033 vnc_flush(vs);
2036 static void send_ext_audio_ack(VncState *vs)
2038 vnc_lock_output(vs);
2039 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2040 vnc_write_u8(vs, 0);
2041 vnc_write_u16(vs, 1);
2042 vnc_framebuffer_update(vs, 0, 0,
2043 pixman_image_get_width(vs->vd->server),
2044 pixman_image_get_height(vs->vd->server),
2045 VNC_ENCODING_AUDIO);
2046 vnc_unlock_output(vs);
2047 vnc_flush(vs);
2050 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2052 int i;
2053 unsigned int enc = 0;
2055 vs->features = 0;
2056 vs->vnc_encoding = 0;
2057 vs->tight.compression = 9;
2058 vs->tight.quality = -1; /* Lossless by default */
2059 vs->absolute = -1;
2062 * Start from the end because the encodings are sent in order of preference.
2063 * This way the preferred encoding (first encoding defined in the array)
2064 * will be set at the end of the loop.
2066 for (i = n_encodings - 1; i >= 0; i--) {
2067 enc = encodings[i];
2068 switch (enc) {
2069 case VNC_ENCODING_RAW:
2070 vs->vnc_encoding = enc;
2071 break;
2072 case VNC_ENCODING_COPYRECT:
2073 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2074 break;
2075 case VNC_ENCODING_HEXTILE:
2076 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2077 vs->vnc_encoding = enc;
2078 break;
2079 case VNC_ENCODING_TIGHT:
2080 vs->features |= VNC_FEATURE_TIGHT_MASK;
2081 vs->vnc_encoding = enc;
2082 break;
2083 #ifdef CONFIG_VNC_PNG
2084 case VNC_ENCODING_TIGHT_PNG:
2085 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2086 vs->vnc_encoding = enc;
2087 break;
2088 #endif
2089 case VNC_ENCODING_ZLIB:
2090 vs->features |= VNC_FEATURE_ZLIB_MASK;
2091 vs->vnc_encoding = enc;
2092 break;
2093 case VNC_ENCODING_ZRLE:
2094 vs->features |= VNC_FEATURE_ZRLE_MASK;
2095 vs->vnc_encoding = enc;
2096 break;
2097 case VNC_ENCODING_ZYWRLE:
2098 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2099 vs->vnc_encoding = enc;
2100 break;
2101 case VNC_ENCODING_DESKTOPRESIZE:
2102 vs->features |= VNC_FEATURE_RESIZE_MASK;
2103 break;
2104 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2105 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2106 break;
2107 case VNC_ENCODING_RICH_CURSOR:
2108 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2109 break;
2110 case VNC_ENCODING_EXT_KEY_EVENT:
2111 send_ext_key_event_ack(vs);
2112 break;
2113 case VNC_ENCODING_AUDIO:
2114 send_ext_audio_ack(vs);
2115 break;
2116 case VNC_ENCODING_WMVi:
2117 vs->features |= VNC_FEATURE_WMVI_MASK;
2118 break;
2119 case VNC_ENCODING_LED_STATE:
2120 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2121 break;
2122 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2123 vs->tight.compression = (enc & 0x0F);
2124 break;
2125 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2126 if (vs->vd->lossy) {
2127 vs->tight.quality = (enc & 0x0F);
2129 break;
2130 default:
2131 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2132 break;
2135 vnc_desktop_resize(vs);
2136 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2137 vnc_led_state_change(vs);
2140 static void set_pixel_conversion(VncState *vs)
2142 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2144 if (fmt == VNC_SERVER_FB_FORMAT) {
2145 vs->write_pixels = vnc_write_pixels_copy;
2146 vnc_hextile_set_pixel_conversion(vs, 0);
2147 } else {
2148 vs->write_pixels = vnc_write_pixels_generic;
2149 vnc_hextile_set_pixel_conversion(vs, 1);
2153 static void set_pixel_format(VncState *vs,
2154 int bits_per_pixel, int depth,
2155 int big_endian_flag, int true_color_flag,
2156 int red_max, int green_max, int blue_max,
2157 int red_shift, int green_shift, int blue_shift)
2159 if (!true_color_flag) {
2160 vnc_client_error(vs);
2161 return;
2164 switch (bits_per_pixel) {
2165 case 8:
2166 case 16:
2167 case 32:
2168 break;
2169 default:
2170 vnc_client_error(vs);
2171 return;
2174 vs->client_pf.rmax = red_max;
2175 vs->client_pf.rbits = hweight_long(red_max);
2176 vs->client_pf.rshift = red_shift;
2177 vs->client_pf.rmask = red_max << red_shift;
2178 vs->client_pf.gmax = green_max;
2179 vs->client_pf.gbits = hweight_long(green_max);
2180 vs->client_pf.gshift = green_shift;
2181 vs->client_pf.gmask = green_max << green_shift;
2182 vs->client_pf.bmax = blue_max;
2183 vs->client_pf.bbits = hweight_long(blue_max);
2184 vs->client_pf.bshift = blue_shift;
2185 vs->client_pf.bmask = blue_max << blue_shift;
2186 vs->client_pf.bits_per_pixel = bits_per_pixel;
2187 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2188 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2189 vs->client_be = big_endian_flag;
2191 set_pixel_conversion(vs);
2193 graphic_hw_invalidate(vs->vd->dcl.con);
2194 graphic_hw_update(vs->vd->dcl.con);
2197 static void pixel_format_message (VncState *vs) {
2198 char pad[3] = { 0, 0, 0 };
2200 vs->client_pf = qemu_default_pixelformat(32);
2202 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2203 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2205 #ifdef HOST_WORDS_BIGENDIAN
2206 vnc_write_u8(vs, 1); /* big-endian-flag */
2207 #else
2208 vnc_write_u8(vs, 0); /* big-endian-flag */
2209 #endif
2210 vnc_write_u8(vs, 1); /* true-color-flag */
2211 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2212 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2213 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2214 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2215 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2216 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2217 vnc_write(vs, pad, 3); /* padding */
2219 vnc_hextile_set_pixel_conversion(vs, 0);
2220 vs->write_pixels = vnc_write_pixels_copy;
2223 static void vnc_colordepth(VncState *vs)
2225 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2226 /* Sending a WMVi message to notify the client*/
2227 vnc_lock_output(vs);
2228 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2229 vnc_write_u8(vs, 0);
2230 vnc_write_u16(vs, 1); /* number of rects */
2231 vnc_framebuffer_update(vs, 0, 0,
2232 pixman_image_get_width(vs->vd->server),
2233 pixman_image_get_height(vs->vd->server),
2234 VNC_ENCODING_WMVi);
2235 pixel_format_message(vs);
2236 vnc_unlock_output(vs);
2237 vnc_flush(vs);
2238 } else {
2239 set_pixel_conversion(vs);
2243 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2245 int i;
2246 uint16_t limit;
2247 VncDisplay *vd = vs->vd;
2249 if (data[0] > 3) {
2250 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2253 switch (data[0]) {
2254 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2255 if (len == 1)
2256 return 20;
2258 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2259 read_u8(data, 6), read_u8(data, 7),
2260 read_u16(data, 8), read_u16(data, 10),
2261 read_u16(data, 12), read_u8(data, 14),
2262 read_u8(data, 15), read_u8(data, 16));
2263 break;
2264 case VNC_MSG_CLIENT_SET_ENCODINGS:
2265 if (len == 1)
2266 return 4;
2268 if (len == 4) {
2269 limit = read_u16(data, 2);
2270 if (limit > 0)
2271 return 4 + (limit * 4);
2272 } else
2273 limit = read_u16(data, 2);
2275 for (i = 0; i < limit; i++) {
2276 int32_t val = read_s32(data, 4 + (i * 4));
2277 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2280 set_encodings(vs, (int32_t *)(data + 4), limit);
2281 break;
2282 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2283 if (len == 1)
2284 return 10;
2286 framebuffer_update_request(vs,
2287 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2288 read_u16(data, 6), read_u16(data, 8));
2289 break;
2290 case VNC_MSG_CLIENT_KEY_EVENT:
2291 if (len == 1)
2292 return 8;
2294 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2295 break;
2296 case VNC_MSG_CLIENT_POINTER_EVENT:
2297 if (len == 1)
2298 return 6;
2300 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2301 break;
2302 case VNC_MSG_CLIENT_CUT_TEXT:
2303 if (len == 1) {
2304 return 8;
2306 if (len == 8) {
2307 uint32_t dlen = read_u32(data, 4);
2308 if (dlen > (1 << 20)) {
2309 error_report("vnc: client_cut_text msg payload has %u bytes"
2310 " which exceeds our limit of 1MB.", dlen);
2311 vnc_client_error(vs);
2312 break;
2314 if (dlen > 0) {
2315 return 8 + dlen;
2319 client_cut_text(vs, read_u32(data, 4), data + 8);
2320 break;
2321 case VNC_MSG_CLIENT_QEMU:
2322 if (len == 1)
2323 return 2;
2325 switch (read_u8(data, 1)) {
2326 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2327 if (len == 2)
2328 return 12;
2330 ext_key_event(vs, read_u16(data, 2),
2331 read_u32(data, 4), read_u32(data, 8));
2332 break;
2333 case VNC_MSG_CLIENT_QEMU_AUDIO:
2334 if (len == 2)
2335 return 4;
2337 switch (read_u16 (data, 2)) {
2338 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2339 audio_add(vs);
2340 break;
2341 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2342 audio_del(vs);
2343 break;
2344 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2345 if (len == 4)
2346 return 10;
2347 switch (read_u8(data, 4)) {
2348 case 0: vs->as.fmt = AUD_FMT_U8; break;
2349 case 1: vs->as.fmt = AUD_FMT_S8; break;
2350 case 2: vs->as.fmt = AUD_FMT_U16; break;
2351 case 3: vs->as.fmt = AUD_FMT_S16; break;
2352 case 4: vs->as.fmt = AUD_FMT_U32; break;
2353 case 5: vs->as.fmt = AUD_FMT_S32; break;
2354 default:
2355 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2356 vnc_client_error(vs);
2357 break;
2359 vs->as.nchannels = read_u8(data, 5);
2360 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2361 VNC_DEBUG("Invalid audio channel coount %d\n",
2362 read_u8(data, 5));
2363 vnc_client_error(vs);
2364 break;
2366 vs->as.freq = read_u32(data, 6);
2367 break;
2368 default:
2369 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2370 vnc_client_error(vs);
2371 break;
2373 break;
2375 default:
2376 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2377 vnc_client_error(vs);
2378 break;
2380 break;
2381 default:
2382 VNC_DEBUG("Msg: %d\n", data[0]);
2383 vnc_client_error(vs);
2384 break;
2387 vnc_read_when(vs, protocol_client_msg, 1);
2388 return 0;
2391 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2393 char buf[1024];
2394 VncShareMode mode;
2395 int size;
2397 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2398 switch (vs->vd->share_policy) {
2399 case VNC_SHARE_POLICY_IGNORE:
2401 * Ignore the shared flag. Nothing to do here.
2403 * Doesn't conform to the rfb spec but is traditional qemu
2404 * behavior, thus left here as option for compatibility
2405 * reasons.
2407 break;
2408 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2410 * Policy: Allow clients ask for exclusive access.
2412 * Implementation: When a client asks for exclusive access,
2413 * disconnect all others. Shared connects are allowed as long
2414 * as no exclusive connection exists.
2416 * This is how the rfb spec suggests to handle the shared flag.
2418 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2419 VncState *client;
2420 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2421 if (vs == client) {
2422 continue;
2424 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2425 client->share_mode != VNC_SHARE_MODE_SHARED) {
2426 continue;
2428 vnc_disconnect_start(client);
2431 if (mode == VNC_SHARE_MODE_SHARED) {
2432 if (vs->vd->num_exclusive > 0) {
2433 vnc_disconnect_start(vs);
2434 return 0;
2437 break;
2438 case VNC_SHARE_POLICY_FORCE_SHARED:
2440 * Policy: Shared connects only.
2441 * Implementation: Disallow clients asking for exclusive access.
2443 * Useful for shared desktop sessions where you don't want
2444 * someone forgetting to say -shared when running the vnc
2445 * client disconnect everybody else.
2447 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2448 vnc_disconnect_start(vs);
2449 return 0;
2451 break;
2453 vnc_set_share_mode(vs, mode);
2455 if (vs->vd->num_shared > vs->vd->connections_limit) {
2456 vnc_disconnect_start(vs);
2457 return 0;
2460 vs->client_width = pixman_image_get_width(vs->vd->server);
2461 vs->client_height = pixman_image_get_height(vs->vd->server);
2462 vnc_write_u16(vs, vs->client_width);
2463 vnc_write_u16(vs, vs->client_height);
2465 pixel_format_message(vs);
2467 if (qemu_name)
2468 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2469 else
2470 size = snprintf(buf, sizeof(buf), "QEMU");
2472 vnc_write_u32(vs, size);
2473 vnc_write(vs, buf, size);
2474 vnc_flush(vs);
2476 vnc_client_cache_auth(vs);
2477 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2479 vnc_read_when(vs, protocol_client_msg, 1);
2481 return 0;
2484 void start_client_init(VncState *vs)
2486 vnc_read_when(vs, protocol_client_init, 1);
2489 static void make_challenge(VncState *vs)
2491 int i;
2493 srand(time(NULL)+getpid()+getpid()*987654+rand());
2495 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2496 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2499 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2501 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2502 size_t i, pwlen;
2503 unsigned char key[8];
2504 time_t now = time(NULL);
2505 QCryptoCipher *cipher = NULL;
2506 Error *err = NULL;
2508 if (!vs->vd->password) {
2509 VNC_DEBUG("No password configured on server");
2510 goto reject;
2512 if (vs->vd->expires < now) {
2513 VNC_DEBUG("Password is expired");
2514 goto reject;
2517 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2519 /* Calculate the expected challenge response */
2520 pwlen = strlen(vs->vd->password);
2521 for (i=0; i<sizeof(key); i++)
2522 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2524 cipher = qcrypto_cipher_new(
2525 QCRYPTO_CIPHER_ALG_DES_RFB,
2526 QCRYPTO_CIPHER_MODE_ECB,
2527 key, G_N_ELEMENTS(key),
2528 &err);
2529 if (!cipher) {
2530 VNC_DEBUG("Cannot initialize cipher %s",
2531 error_get_pretty(err));
2532 error_free(err);
2533 goto reject;
2536 if (qcrypto_cipher_encrypt(cipher,
2537 vs->challenge,
2538 response,
2539 VNC_AUTH_CHALLENGE_SIZE,
2540 &err) < 0) {
2541 VNC_DEBUG("Cannot encrypt challenge %s",
2542 error_get_pretty(err));
2543 error_free(err);
2544 goto reject;
2547 /* Compare expected vs actual challenge response */
2548 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2549 VNC_DEBUG("Client challenge response did not match\n");
2550 goto reject;
2551 } else {
2552 VNC_DEBUG("Accepting VNC challenge response\n");
2553 vnc_write_u32(vs, 0); /* Accept auth */
2554 vnc_flush(vs);
2556 start_client_init(vs);
2559 qcrypto_cipher_free(cipher);
2560 return 0;
2562 reject:
2563 vnc_write_u32(vs, 1); /* Reject auth */
2564 if (vs->minor >= 8) {
2565 static const char err[] = "Authentication failed";
2566 vnc_write_u32(vs, sizeof(err));
2567 vnc_write(vs, err, sizeof(err));
2569 vnc_flush(vs);
2570 vnc_client_error(vs);
2571 qcrypto_cipher_free(cipher);
2572 return 0;
2575 void start_auth_vnc(VncState *vs)
2577 make_challenge(vs);
2578 /* Send client a 'random' challenge */
2579 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2580 vnc_flush(vs);
2582 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2586 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2588 /* We only advertise 1 auth scheme at a time, so client
2589 * must pick the one we sent. Verify this */
2590 if (data[0] != vs->auth) { /* Reject auth */
2591 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2592 vnc_write_u32(vs, 1);
2593 if (vs->minor >= 8) {
2594 static const char err[] = "Authentication failed";
2595 vnc_write_u32(vs, sizeof(err));
2596 vnc_write(vs, err, sizeof(err));
2598 vnc_client_error(vs);
2599 } else { /* Accept requested auth */
2600 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2601 switch (vs->auth) {
2602 case VNC_AUTH_NONE:
2603 VNC_DEBUG("Accept auth none\n");
2604 if (vs->minor >= 8) {
2605 vnc_write_u32(vs, 0); /* Accept auth completion */
2606 vnc_flush(vs);
2608 start_client_init(vs);
2609 break;
2611 case VNC_AUTH_VNC:
2612 VNC_DEBUG("Start VNC auth\n");
2613 start_auth_vnc(vs);
2614 break;
2616 case VNC_AUTH_VENCRYPT:
2617 VNC_DEBUG("Accept VeNCrypt auth\n");
2618 start_auth_vencrypt(vs);
2619 break;
2621 #ifdef CONFIG_VNC_SASL
2622 case VNC_AUTH_SASL:
2623 VNC_DEBUG("Accept SASL auth\n");
2624 start_auth_sasl(vs);
2625 break;
2626 #endif /* CONFIG_VNC_SASL */
2628 default: /* Should not be possible, but just in case */
2629 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2630 vnc_write_u8(vs, 1);
2631 if (vs->minor >= 8) {
2632 static const char err[] = "Authentication failed";
2633 vnc_write_u32(vs, sizeof(err));
2634 vnc_write(vs, err, sizeof(err));
2636 vnc_client_error(vs);
2639 return 0;
2642 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2644 char local[13];
2646 memcpy(local, version, 12);
2647 local[12] = 0;
2649 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2650 VNC_DEBUG("Malformed protocol version %s\n", local);
2651 vnc_client_error(vs);
2652 return 0;
2654 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2655 if (vs->major != 3 ||
2656 (vs->minor != 3 &&
2657 vs->minor != 4 &&
2658 vs->minor != 5 &&
2659 vs->minor != 7 &&
2660 vs->minor != 8)) {
2661 VNC_DEBUG("Unsupported client version\n");
2662 vnc_write_u32(vs, VNC_AUTH_INVALID);
2663 vnc_flush(vs);
2664 vnc_client_error(vs);
2665 return 0;
2667 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2668 * as equivalent to v3.3 by servers
2670 if (vs->minor == 4 || vs->minor == 5)
2671 vs->minor = 3;
2673 if (vs->minor == 3) {
2674 if (vs->auth == VNC_AUTH_NONE) {
2675 VNC_DEBUG("Tell client auth none\n");
2676 vnc_write_u32(vs, vs->auth);
2677 vnc_flush(vs);
2678 start_client_init(vs);
2679 } else if (vs->auth == VNC_AUTH_VNC) {
2680 VNC_DEBUG("Tell client VNC auth\n");
2681 vnc_write_u32(vs, vs->auth);
2682 vnc_flush(vs);
2683 start_auth_vnc(vs);
2684 } else {
2685 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2686 vnc_write_u32(vs, VNC_AUTH_INVALID);
2687 vnc_flush(vs);
2688 vnc_client_error(vs);
2690 } else {
2691 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2692 vnc_write_u8(vs, 1); /* num auth */
2693 vnc_write_u8(vs, vs->auth);
2694 vnc_read_when(vs, protocol_client_auth, 1);
2695 vnc_flush(vs);
2698 return 0;
2701 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2703 struct VncSurface *vs = &vd->guest;
2705 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2708 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2710 int i, j;
2712 w = (x + w) / VNC_STAT_RECT;
2713 h = (y + h) / VNC_STAT_RECT;
2714 x /= VNC_STAT_RECT;
2715 y /= VNC_STAT_RECT;
2717 for (j = y; j <= h; j++) {
2718 for (i = x; i <= w; i++) {
2719 vs->lossy_rect[j][i] = 1;
2724 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2726 VncState *vs;
2727 int sty = y / VNC_STAT_RECT;
2728 int stx = x / VNC_STAT_RECT;
2729 int has_dirty = 0;
2731 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2732 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2734 QTAILQ_FOREACH(vs, &vd->clients, next) {
2735 int j;
2737 /* kernel send buffers are full -> refresh later */
2738 if (vs->output.offset) {
2739 continue;
2742 if (!vs->lossy_rect[sty][stx]) {
2743 continue;
2746 vs->lossy_rect[sty][stx] = 0;
2747 for (j = 0; j < VNC_STAT_RECT; ++j) {
2748 bitmap_set(vs->dirty[y + j],
2749 x / VNC_DIRTY_PIXELS_PER_BIT,
2750 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2752 has_dirty++;
2755 return has_dirty;
2758 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2760 int width = pixman_image_get_width(vd->guest.fb);
2761 int height = pixman_image_get_height(vd->guest.fb);
2762 int x, y;
2763 struct timeval res;
2764 int has_dirty = 0;
2766 for (y = 0; y < height; y += VNC_STAT_RECT) {
2767 for (x = 0; x < width; x += VNC_STAT_RECT) {
2768 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2770 rect->updated = false;
2774 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2776 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2777 return has_dirty;
2779 vd->guest.last_freq_check = *tv;
2781 for (y = 0; y < height; y += VNC_STAT_RECT) {
2782 for (x = 0; x < width; x += VNC_STAT_RECT) {
2783 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2784 int count = ARRAY_SIZE(rect->times);
2785 struct timeval min, max;
2787 if (!timerisset(&rect->times[count - 1])) {
2788 continue ;
2791 max = rect->times[(rect->idx + count - 1) % count];
2792 qemu_timersub(tv, &max, &res);
2794 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2795 rect->freq = 0;
2796 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2797 memset(rect->times, 0, sizeof (rect->times));
2798 continue ;
2801 min = rect->times[rect->idx];
2802 max = rect->times[(rect->idx + count - 1) % count];
2803 qemu_timersub(&max, &min, &res);
2805 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2806 rect->freq /= count;
2807 rect->freq = 1. / rect->freq;
2810 return has_dirty;
2813 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2815 int i, j;
2816 double total = 0;
2817 int num = 0;
2819 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2820 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2822 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2823 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2824 total += vnc_stat_rect(vs->vd, i, j)->freq;
2825 num++;
2829 if (num) {
2830 return total / num;
2831 } else {
2832 return 0;
2836 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2838 VncRectStat *rect;
2840 rect = vnc_stat_rect(vd, x, y);
2841 if (rect->updated) {
2842 return ;
2844 rect->times[rect->idx] = *tv;
2845 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2846 rect->updated = true;
2849 static int vnc_refresh_server_surface(VncDisplay *vd)
2851 int width = MIN(pixman_image_get_width(vd->guest.fb),
2852 pixman_image_get_width(vd->server));
2853 int height = MIN(pixman_image_get_height(vd->guest.fb),
2854 pixman_image_get_height(vd->server));
2855 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2856 uint8_t *guest_row0 = NULL, *server_row0;
2857 VncState *vs;
2858 int has_dirty = 0;
2859 pixman_image_t *tmpbuf = NULL;
2861 struct timeval tv = { 0, 0 };
2863 if (!vd->non_adaptive) {
2864 gettimeofday(&tv, NULL);
2865 has_dirty = vnc_update_stats(vd, &tv);
2869 * Walk through the guest dirty map.
2870 * Check and copy modified bits from guest to server surface.
2871 * Update server dirty map.
2873 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2874 server_stride = guest_stride = guest_ll =
2875 pixman_image_get_stride(vd->server);
2876 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2877 server_stride);
2878 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2879 int width = pixman_image_get_width(vd->server);
2880 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2881 } else {
2882 int guest_bpp =
2883 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2884 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2885 guest_stride = pixman_image_get_stride(vd->guest.fb);
2886 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2888 line_bytes = MIN(server_stride, guest_ll);
2890 for (;;) {
2891 int x;
2892 uint8_t *guest_ptr, *server_ptr;
2893 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2894 height * VNC_DIRTY_BPL(&vd->guest),
2895 y * VNC_DIRTY_BPL(&vd->guest));
2896 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2897 /* no more dirty bits */
2898 break;
2900 y = offset / VNC_DIRTY_BPL(&vd->guest);
2901 x = offset % VNC_DIRTY_BPL(&vd->guest);
2903 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2905 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2906 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2907 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2908 } else {
2909 guest_ptr = guest_row0 + y * guest_stride;
2911 guest_ptr += x * cmp_bytes;
2913 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2914 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2915 int _cmp_bytes = cmp_bytes;
2916 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2917 continue;
2919 if ((x + 1) * cmp_bytes > line_bytes) {
2920 _cmp_bytes = line_bytes - x * cmp_bytes;
2922 assert(_cmp_bytes >= 0);
2923 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2924 continue;
2926 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2927 if (!vd->non_adaptive) {
2928 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2929 y, &tv);
2931 QTAILQ_FOREACH(vs, &vd->clients, next) {
2932 set_bit(x, vs->dirty[y]);
2934 has_dirty++;
2937 y++;
2939 qemu_pixman_image_unref(tmpbuf);
2940 return has_dirty;
2943 static void vnc_refresh(DisplayChangeListener *dcl)
2945 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2946 VncState *vs, *vn;
2947 int has_dirty, rects = 0;
2949 if (QTAILQ_EMPTY(&vd->clients)) {
2950 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2951 return;
2954 graphic_hw_update(vd->dcl.con);
2956 if (vnc_trylock_display(vd)) {
2957 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2958 return;
2961 has_dirty = vnc_refresh_server_surface(vd);
2962 vnc_unlock_display(vd);
2964 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2965 rects += vnc_update_client(vs, has_dirty, false);
2966 /* vs might be free()ed here */
2969 if (has_dirty && rects) {
2970 vd->dcl.update_interval /= 2;
2971 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2972 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2974 } else {
2975 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2976 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2977 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2982 static void vnc_connect(VncDisplay *vd, int csock,
2983 bool skipauth, bool websocket)
2985 VncState *vs = g_malloc0(sizeof(VncState));
2986 int i;
2988 vs->csock = csock;
2989 vs->vd = vd;
2991 if (skipauth) {
2992 vs->auth = VNC_AUTH_NONE;
2993 vs->subauth = VNC_AUTH_INVALID;
2994 } else {
2995 if (websocket) {
2996 vs->auth = vd->ws_auth;
2997 vs->subauth = VNC_AUTH_INVALID;
2998 } else {
2999 vs->auth = vd->auth;
3000 vs->subauth = vd->subauth;
3003 VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
3004 csock, websocket, vs->auth, vs->subauth);
3006 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3007 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3008 vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));
3011 VNC_DEBUG("New client on socket %d\n", csock);
3012 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3013 qemu_set_nonblock(vs->csock);
3014 if (websocket) {
3015 vs->websocket = 1;
3016 if (vd->ws_tls) {
3017 qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io, NULL, vs);
3018 } else {
3019 qemu_set_fd_handler(vs->csock, vncws_handshake_read, NULL, vs);
3021 } else
3023 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
3026 vnc_client_cache_addr(vs);
3027 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3028 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3030 if (!vs->websocket) {
3031 vnc_init_state(vs);
3034 if (vd->num_connecting > vd->connections_limit) {
3035 QTAILQ_FOREACH(vs, &vd->clients, next) {
3036 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3037 vnc_disconnect_start(vs);
3038 return;
3044 void vnc_init_state(VncState *vs)
3046 vs->initialized = true;
3047 VncDisplay *vd = vs->vd;
3049 vs->last_x = -1;
3050 vs->last_y = -1;
3052 vs->as.freq = 44100;
3053 vs->as.nchannels = 2;
3054 vs->as.fmt = AUD_FMT_S16;
3055 vs->as.endianness = 0;
3057 qemu_mutex_init(&vs->output_mutex);
3058 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3060 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3062 graphic_hw_update(vd->dcl.con);
3064 vnc_write(vs, "RFB 003.008\n", 12);
3065 vnc_flush(vs);
3066 vnc_read_when(vs, protocol_version, 12);
3067 reset_keys(vs);
3068 if (vs->vd->lock_key_sync)
3069 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3071 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3072 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3074 /* vs might be free()ed here */
3077 static void vnc_listen_read(void *opaque, bool websocket)
3079 VncDisplay *vs = opaque;
3080 struct sockaddr_in addr;
3081 socklen_t addrlen = sizeof(addr);
3082 int csock;
3084 /* Catch-up */
3085 graphic_hw_update(vs->dcl.con);
3086 if (websocket) {
3087 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
3088 } else {
3089 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
3092 if (csock != -1) {
3093 socket_set_nodelay(csock);
3094 vnc_connect(vs, csock, false, websocket);
3098 static void vnc_listen_regular_read(void *opaque)
3100 vnc_listen_read(opaque, false);
3103 static void vnc_listen_websocket_read(void *opaque)
3105 vnc_listen_read(opaque, true);
3108 static const DisplayChangeListenerOps dcl_ops = {
3109 .dpy_name = "vnc",
3110 .dpy_refresh = vnc_refresh,
3111 .dpy_gfx_copy = vnc_dpy_copy,
3112 .dpy_gfx_update = vnc_dpy_update,
3113 .dpy_gfx_switch = vnc_dpy_switch,
3114 .dpy_gfx_check_format = qemu_pixman_check_format,
3115 .dpy_mouse_set = vnc_mouse_set,
3116 .dpy_cursor_define = vnc_dpy_cursor_define,
3119 void vnc_display_init(const char *id)
3121 VncDisplay *vs;
3123 if (vnc_display_find(id) != NULL) {
3124 return;
3126 vs = g_malloc0(sizeof(*vs));
3128 vs->id = strdup(id);
3129 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3131 vs->lsock = -1;
3132 vs->lwebsock = -1;
3134 QTAILQ_INIT(&vs->clients);
3135 vs->expires = TIME_MAX;
3137 if (keyboard_layout) {
3138 trace_vnc_key_map_init(keyboard_layout);
3139 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3140 } else {
3141 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3144 if (!vs->kbd_layout)
3145 exit(1);
3147 qemu_mutex_init(&vs->mutex);
3148 vnc_start_worker_thread();
3150 vs->dcl.ops = &dcl_ops;
3151 register_displaychangelistener(&vs->dcl);
3155 static void vnc_display_close(VncDisplay *vs)
3157 if (!vs)
3158 return;
3159 vs->enabled = false;
3160 vs->is_unix = false;
3161 if (vs->lsock != -1) {
3162 qemu_set_fd_handler(vs->lsock, NULL, NULL, NULL);
3163 close(vs->lsock);
3164 vs->lsock = -1;
3166 vs->ws_enabled = false;
3167 if (vs->lwebsock != -1) {
3168 qemu_set_fd_handler(vs->lwebsock, NULL, NULL, NULL);
3169 close(vs->lwebsock);
3170 vs->lwebsock = -1;
3172 vs->auth = VNC_AUTH_INVALID;
3173 vs->subauth = VNC_AUTH_INVALID;
3174 if (vs->tlscreds) {
3175 object_unparent(OBJECT(vs->tlscreds));
3177 g_free(vs->tlsaclname);
3178 vs->tlsaclname = NULL;
3181 int vnc_display_password(const char *id, const char *password)
3183 VncDisplay *vs = vnc_display_find(id);
3185 if (!vs) {
3186 return -EINVAL;
3188 if (vs->auth == VNC_AUTH_NONE) {
3189 error_printf_unless_qmp("If you want use passwords please enable "
3190 "password auth using '-vnc ${dpy},password'.");
3191 return -EINVAL;
3194 g_free(vs->password);
3195 vs->password = g_strdup(password);
3197 return 0;
3200 int vnc_display_pw_expire(const char *id, time_t expires)
3202 VncDisplay *vs = vnc_display_find(id);
3204 if (!vs) {
3205 return -EINVAL;
3208 vs->expires = expires;
3209 return 0;
3212 char *vnc_display_local_addr(const char *id)
3214 VncDisplay *vs = vnc_display_find(id);
3216 assert(vs);
3217 return vnc_socket_local_addr("%s:%s", vs->lsock);
3220 static QemuOptsList qemu_vnc_opts = {
3221 .name = "vnc",
3222 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3223 .implied_opt_name = "vnc",
3224 .desc = {
3226 .name = "vnc",
3227 .type = QEMU_OPT_STRING,
3229 .name = "websocket",
3230 .type = QEMU_OPT_STRING,
3232 .name = "tls-creds",
3233 .type = QEMU_OPT_STRING,
3235 /* Deprecated in favour of tls-creds */
3236 .name = "x509",
3237 .type = QEMU_OPT_STRING,
3239 .name = "share",
3240 .type = QEMU_OPT_STRING,
3242 .name = "display",
3243 .type = QEMU_OPT_STRING,
3245 .name = "head",
3246 .type = QEMU_OPT_NUMBER,
3248 .name = "connections",
3249 .type = QEMU_OPT_NUMBER,
3251 .name = "to",
3252 .type = QEMU_OPT_NUMBER,
3254 .name = "ipv4",
3255 .type = QEMU_OPT_BOOL,
3257 .name = "ipv6",
3258 .type = QEMU_OPT_BOOL,
3260 .name = "password",
3261 .type = QEMU_OPT_BOOL,
3263 .name = "reverse",
3264 .type = QEMU_OPT_BOOL,
3266 .name = "lock-key-sync",
3267 .type = QEMU_OPT_BOOL,
3269 .name = "sasl",
3270 .type = QEMU_OPT_BOOL,
3272 /* Deprecated in favour of tls-creds */
3273 .name = "tls",
3274 .type = QEMU_OPT_BOOL,
3276 /* Deprecated in favour of tls-creds */
3277 .name = "x509verify",
3278 .type = QEMU_OPT_STRING,
3280 .name = "acl",
3281 .type = QEMU_OPT_BOOL,
3283 .name = "lossy",
3284 .type = QEMU_OPT_BOOL,
3286 .name = "non-adaptive",
3287 .type = QEMU_OPT_BOOL,
3289 { /* end of list */ }
3294 static int
3295 vnc_display_setup_auth(VncDisplay *vs,
3296 bool password,
3297 bool sasl,
3298 bool websocket,
3299 Error **errp)
3302 * We have a choice of 3 authentication options
3304 * 1. none
3305 * 2. vnc
3306 * 3. sasl
3308 * The channel can be run in 2 modes
3310 * 1. clear
3311 * 2. tls
3313 * And TLS can use 2 types of credentials
3315 * 1. anon
3316 * 2. x509
3318 * We thus have 9 possible logical combinations
3320 * 1. clear + none
3321 * 2. clear + vnc
3322 * 3. clear + sasl
3323 * 4. tls + anon + none
3324 * 5. tls + anon + vnc
3325 * 6. tls + anon + sasl
3326 * 7. tls + x509 + none
3327 * 8. tls + x509 + vnc
3328 * 9. tls + x509 + sasl
3330 * These need to be mapped into the VNC auth schemes
3331 * in an appropriate manner. In regular VNC, all the
3332 * TLS options get mapped into VNC_AUTH_VENCRYPT
3333 * sub-auth types.
3335 * In websockets, the https:// protocol already provides
3336 * TLS support, so there is no need to make use of the
3337 * VeNCrypt extension. Furthermore, websockets browser
3338 * clients could not use VeNCrypt even if they wanted to,
3339 * as they cannot control when the TLS handshake takes
3340 * place. Thus there is no option but to rely on https://,
3341 * meaning combinations 4->6 and 7->9 will be mapped to
3342 * VNC auth schemes in the same way as combos 1->3.
3344 * Regardless of fact that we have a different mapping to
3345 * VNC auth mechs for plain VNC vs websockets VNC, the end
3346 * result has the same security characteristics.
3348 if (password) {
3349 if (vs->tlscreds) {
3350 vs->auth = VNC_AUTH_VENCRYPT;
3351 if (websocket) {
3352 vs->ws_tls = true;
3354 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3355 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3356 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3357 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3358 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3359 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3360 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3361 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3362 } else {
3363 error_setg(errp,
3364 "Unsupported TLS cred type %s",
3365 object_get_typename(OBJECT(vs->tlscreds)));
3366 return -1;
3368 } else {
3369 VNC_DEBUG("Initializing VNC server with password auth\n");
3370 vs->auth = VNC_AUTH_VNC;
3371 vs->subauth = VNC_AUTH_INVALID;
3373 if (websocket) {
3374 vs->ws_auth = VNC_AUTH_VNC;
3375 } else {
3376 vs->ws_auth = VNC_AUTH_INVALID;
3378 } else if (sasl) {
3379 if (vs->tlscreds) {
3380 vs->auth = VNC_AUTH_VENCRYPT;
3381 if (websocket) {
3382 vs->ws_tls = true;
3384 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3385 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3386 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3387 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3388 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3389 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3390 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3391 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3392 } else {
3393 error_setg(errp,
3394 "Unsupported TLS cred type %s",
3395 object_get_typename(OBJECT(vs->tlscreds)));
3396 return -1;
3398 } else {
3399 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3400 vs->auth = VNC_AUTH_SASL;
3401 vs->subauth = VNC_AUTH_INVALID;
3403 if (websocket) {
3404 vs->ws_auth = VNC_AUTH_SASL;
3405 } else {
3406 vs->ws_auth = VNC_AUTH_INVALID;
3408 } else {
3409 if (vs->tlscreds) {
3410 vs->auth = VNC_AUTH_VENCRYPT;
3411 if (websocket) {
3412 vs->ws_tls = true;
3414 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3415 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3416 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3417 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3418 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3419 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3420 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3421 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3422 } else {
3423 error_setg(errp,
3424 "Unsupported TLS cred type %s",
3425 object_get_typename(OBJECT(vs->tlscreds)));
3426 return -1;
3428 } else {
3429 VNC_DEBUG("Initializing VNC server with no auth\n");
3430 vs->auth = VNC_AUTH_NONE;
3431 vs->subauth = VNC_AUTH_INVALID;
3433 if (websocket) {
3434 vs->ws_auth = VNC_AUTH_NONE;
3435 } else {
3436 vs->ws_auth = VNC_AUTH_INVALID;
3439 return 0;
3444 * Handle back compat with old CLI syntax by creating some
3445 * suitable QCryptoTLSCreds objects
3447 static QCryptoTLSCreds *
3448 vnc_display_create_creds(bool x509,
3449 bool x509verify,
3450 const char *dir,
3451 const char *id,
3452 Error **errp)
3454 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3455 Object *parent = object_get_objects_root();
3456 Object *creds;
3457 Error *err = NULL;
3459 if (x509) {
3460 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3461 parent,
3462 credsid,
3463 &err,
3464 "endpoint", "server",
3465 "dir", dir,
3466 "verify-peer", x509verify ? "yes" : "no",
3467 NULL);
3468 } else {
3469 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3470 parent,
3471 credsid,
3472 &err,
3473 "endpoint", "server",
3474 NULL);
3477 g_free(credsid);
3479 if (err) {
3480 error_propagate(errp, err);
3481 return NULL;
3484 return QCRYPTO_TLS_CREDS(creds);
3488 void vnc_display_open(const char *id, Error **errp)
3490 VncDisplay *vs = vnc_display_find(id);
3491 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3492 SocketAddress *saddr = NULL, *wsaddr = NULL;
3493 const char *share, *device_id;
3494 QemuConsole *con;
3495 bool password = false;
3496 bool reverse = false;
3497 const char *vnc;
3498 char *h;
3499 const char *credid;
3500 bool sasl = false;
3501 #ifdef CONFIG_VNC_SASL
3502 int saslErr;
3503 #endif
3504 int acl = 0;
3505 int lock_key_sync = 1;
3507 if (!vs) {
3508 error_setg(errp, "VNC display not active");
3509 return;
3511 vnc_display_close(vs);
3513 if (!opts) {
3514 return;
3516 vnc = qemu_opt_get(opts, "vnc");
3517 if (!vnc || strcmp(vnc, "none") == 0) {
3518 return;
3521 h = strrchr(vnc, ':');
3522 if (h) {
3523 size_t hlen = h - vnc;
3525 const char *websocket = qemu_opt_get(opts, "websocket");
3526 int to = qemu_opt_get_number(opts, "to", 0);
3527 bool has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3528 bool has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3530 saddr = g_new0(SocketAddress, 1);
3531 if (websocket) {
3532 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3533 error_setg(errp,
3534 "SHA1 hash support is required for websockets");
3535 goto fail;
3538 wsaddr = g_new0(SocketAddress, 1);
3539 vs->ws_enabled = true;
3542 if (strncmp(vnc, "unix:", 5) == 0) {
3543 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3544 saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
3545 saddr->u.q_unix->path = g_strdup(vnc + 5);
3547 if (vs->ws_enabled) {
3548 error_setg(errp, "UNIX sockets not supported with websock");
3549 goto fail;
3551 } else {
3552 unsigned long long baseport;
3553 saddr->type = SOCKET_ADDRESS_KIND_INET;
3554 saddr->u.inet = g_new0(InetSocketAddress, 1);
3555 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3556 saddr->u.inet->host = g_strndup(vnc + 1, hlen - 2);
3557 } else {
3558 saddr->u.inet->host = g_strndup(vnc, hlen);
3560 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3561 error_setg(errp, "can't convert to a number: %s", h + 1);
3562 goto fail;
3564 if (baseport > 65535 ||
3565 baseport + 5900 > 65535) {
3566 error_setg(errp, "port %s out of range", h + 1);
3567 goto fail;
3569 saddr->u.inet->port = g_strdup_printf(
3570 "%d", (int)baseport + 5900);
3572 if (to) {
3573 saddr->u.inet->has_to = true;
3574 saddr->u.inet->to = to;
3575 saddr->u.inet->has_to = true;
3576 saddr->u.inet->to = to + 5900;
3578 saddr->u.inet->ipv4 = saddr->u.inet->has_ipv4 = has_ipv4;
3579 saddr->u.inet->ipv6 = saddr->u.inet->has_ipv6 = has_ipv6;
3581 if (vs->ws_enabled) {
3582 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3583 wsaddr->u.inet = g_new0(InetSocketAddress, 1);
3584 wsaddr->u.inet->host = g_strdup(saddr->u.inet->host);
3585 wsaddr->u.inet->port = g_strdup(websocket);
3587 if (to) {
3588 wsaddr->u.inet->has_to = true;
3589 wsaddr->u.inet->to = to;
3591 wsaddr->u.inet->ipv4 = wsaddr->u.inet->has_ipv4 = has_ipv4;
3592 wsaddr->u.inet->ipv6 = wsaddr->u.inet->has_ipv6 = has_ipv6;
3595 } else {
3596 error_setg(errp, "no vnc port specified");
3597 goto fail;
3600 password = qemu_opt_get_bool(opts, "password", false);
3601 if (password) {
3602 if (fips_get_state()) {
3603 error_setg(errp,
3604 "VNC password auth disabled due to FIPS mode, "
3605 "consider using the VeNCrypt or SASL authentication "
3606 "methods as an alternative");
3607 goto fail;
3609 if (!qcrypto_cipher_supports(
3610 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3611 error_setg(errp,
3612 "Cipher backend does not support DES RFB algorithm");
3613 goto fail;
3617 reverse = qemu_opt_get_bool(opts, "reverse", false);
3618 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3619 sasl = qemu_opt_get_bool(opts, "sasl", false);
3620 #ifndef CONFIG_VNC_SASL
3621 if (sasl) {
3622 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3623 goto fail;
3625 #endif /* CONFIG_VNC_SASL */
3626 credid = qemu_opt_get(opts, "tls-creds");
3627 if (credid) {
3628 Object *creds;
3629 if (qemu_opt_get(opts, "tls") ||
3630 qemu_opt_get(opts, "x509") ||
3631 qemu_opt_get(opts, "x509verify")) {
3632 error_setg(errp,
3633 "'credid' parameter is mutually exclusive with "
3634 "'tls', 'x509' and 'x509verify' parameters");
3635 goto fail;
3638 creds = object_resolve_path_component(
3639 object_get_objects_root(), credid);
3640 if (!creds) {
3641 error_setg(errp, "No TLS credentials with id '%s'",
3642 credid);
3643 goto fail;
3645 vs->tlscreds = (QCryptoTLSCreds *)
3646 object_dynamic_cast(creds,
3647 TYPE_QCRYPTO_TLS_CREDS);
3648 if (!vs->tlscreds) {
3649 error_setg(errp, "Object with id '%s' is not TLS credentials",
3650 credid);
3651 goto fail;
3653 object_ref(OBJECT(vs->tlscreds));
3655 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3656 error_setg(errp,
3657 "Expecting TLS credentials with a server endpoint");
3658 goto fail;
3660 } else {
3661 const char *path;
3662 bool tls = false, x509 = false, x509verify = false;
3663 tls = qemu_opt_get_bool(opts, "tls", false);
3664 if (tls) {
3665 path = qemu_opt_get(opts, "x509");
3667 if (path) {
3668 x509 = true;
3669 } else {
3670 path = qemu_opt_get(opts, "x509verify");
3671 if (path) {
3672 x509 = true;
3673 x509verify = true;
3676 vs->tlscreds = vnc_display_create_creds(x509,
3677 x509verify,
3678 path,
3679 vs->id,
3680 errp);
3681 if (!vs->tlscreds) {
3682 goto fail;
3686 acl = qemu_opt_get_bool(opts, "acl", false);
3688 share = qemu_opt_get(opts, "share");
3689 if (share) {
3690 if (strcmp(share, "ignore") == 0) {
3691 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3692 } else if (strcmp(share, "allow-exclusive") == 0) {
3693 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3694 } else if (strcmp(share, "force-shared") == 0) {
3695 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3696 } else {
3697 error_setg(errp, "unknown vnc share= option");
3698 goto fail;
3700 } else {
3701 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3703 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3705 #ifdef CONFIG_VNC_JPEG
3706 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3707 #endif
3708 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3709 /* adaptive updates are only used with tight encoding and
3710 * if lossy updates are enabled so we can disable all the
3711 * calculations otherwise */
3712 if (!vs->lossy) {
3713 vs->non_adaptive = true;
3716 if (acl) {
3717 if (strcmp(vs->id, "default") == 0) {
3718 vs->tlsaclname = g_strdup("vnc.x509dname");
3719 } else {
3720 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3722 qemu_acl_init(vs->tlsaclname);
3724 #ifdef CONFIG_VNC_SASL
3725 if (acl && sasl) {
3726 char *aclname;
3728 if (strcmp(vs->id, "default") == 0) {
3729 aclname = g_strdup("vnc.username");
3730 } else {
3731 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3733 vs->sasl.acl = qemu_acl_init(aclname);
3734 g_free(aclname);
3736 #endif
3738 if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
3739 goto fail;
3742 #ifdef CONFIG_VNC_SASL
3743 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3744 error_setg(errp, "Failed to initialize SASL auth: %s",
3745 sasl_errstring(saslErr, NULL, NULL));
3746 goto fail;
3748 #endif
3749 vs->lock_key_sync = lock_key_sync;
3751 device_id = qemu_opt_get(opts, "display");
3752 if (device_id) {
3753 DeviceState *dev;
3754 int head = qemu_opt_get_number(opts, "head", 0);
3756 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3757 if (dev == NULL) {
3758 error_setg(errp, "Device '%s' not found", device_id);
3759 goto fail;
3762 con = qemu_console_lookup_by_device(dev, head);
3763 if (con == NULL) {
3764 error_setg(errp, "Device %s is not bound to a QemuConsole",
3765 device_id);
3766 goto fail;
3768 } else {
3769 con = NULL;
3772 if (con != vs->dcl.con) {
3773 unregister_displaychangelistener(&vs->dcl);
3774 vs->dcl.con = con;
3775 register_displaychangelistener(&vs->dcl);
3778 if (reverse) {
3779 /* connect to viewer */
3780 int csock;
3781 vs->lsock = -1;
3782 vs->lwebsock = -1;
3783 if (vs->ws_enabled) {
3784 error_setg(errp, "Cannot use websockets in reverse mode");
3785 goto fail;
3787 csock = socket_connect(saddr, errp, NULL, NULL);
3788 if (csock < 0) {
3789 goto fail;
3791 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3792 vnc_connect(vs, csock, false, false);
3793 } else {
3794 /* listen for connects */
3795 vs->lsock = socket_listen(saddr, errp);
3796 if (vs->lsock < 0) {
3797 goto fail;
3799 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3800 if (vs->ws_enabled) {
3801 vs->lwebsock = socket_listen(wsaddr, errp);
3802 if (vs->lwebsock < 0) {
3803 if (vs->lsock != -1) {
3804 close(vs->lsock);
3805 vs->lsock = -1;
3807 goto fail;
3810 vs->enabled = true;
3811 qemu_set_fd_handler(vs->lsock, vnc_listen_regular_read, NULL, vs);
3812 if (vs->ws_enabled) {
3813 qemu_set_fd_handler(vs->lwebsock, vnc_listen_websocket_read,
3814 NULL, vs);
3818 qapi_free_SocketAddress(saddr);
3819 qapi_free_SocketAddress(wsaddr);
3820 return;
3822 fail:
3823 qapi_free_SocketAddress(saddr);
3824 qapi_free_SocketAddress(wsaddr);
3825 vs->enabled = false;
3826 vs->ws_enabled = false;
3829 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3831 VncDisplay *vs = vnc_display_find(id);
3833 if (!vs) {
3834 return;
3836 vnc_connect(vs, csock, skipauth, false);
3839 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3841 int i = 2;
3842 char *id;
3844 id = g_strdup("default");
3845 while (qemu_opts_find(olist, id)) {
3846 g_free(id);
3847 id = g_strdup_printf("vnc%d", i++);
3849 qemu_opts_set_id(opts, id);
3852 QemuOpts *vnc_parse(const char *str, Error **errp)
3854 QemuOptsList *olist = qemu_find_opts("vnc");
3855 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3856 const char *id;
3858 if (!opts) {
3859 return NULL;
3862 id = qemu_opts_id(opts);
3863 if (!id) {
3864 /* auto-assign id if not present */
3865 vnc_auto_assign_id(olist, opts);
3867 return opts;
3870 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3872 Error *local_err = NULL;
3873 char *id = (char *)qemu_opts_id(opts);
3875 assert(id);
3876 vnc_display_init(id);
3877 vnc_display_open(id, &local_err);
3878 if (local_err != NULL) {
3879 error_report("Failed to start VNC server: %s",
3880 error_get_pretty(local_err));
3881 error_free(local_err);
3882 exit(1);
3884 return 0;
3887 static void vnc_register_config(void)
3889 qemu_add_opts(&qemu_vnc_opts);
3891 machine_init(vnc_register_config);