memory: inline a few small accessors
[qemu/ar7.git] / ui / vnc.c
blobb9c57fff0561959bb73cbb356dfbbb416eb40936
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 int vnc_width(VncDisplay *vd)
620 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
621 VNC_DIRTY_PIXELS_PER_BIT));
624 static int vnc_height(VncDisplay *vd)
626 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
629 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
630 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
631 VncDisplay *vd,
632 int x, int y, int w, int h)
634 int width = vnc_width(vd);
635 int height = vnc_height(vd);
637 /* this is needed this to ensure we updated all affected
638 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
639 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
640 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
642 x = MIN(x, width);
643 y = MIN(y, height);
644 w = MIN(x + w, width) - x;
645 h = MIN(y + h, height);
647 for (; y < h; y++) {
648 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
649 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
653 static void vnc_dpy_update(DisplayChangeListener *dcl,
654 int x, int y, int w, int h)
656 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
657 struct VncSurface *s = &vd->guest;
659 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
662 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
663 int32_t encoding)
665 vnc_write_u16(vs, x);
666 vnc_write_u16(vs, y);
667 vnc_write_u16(vs, w);
668 vnc_write_u16(vs, h);
670 vnc_write_s32(vs, encoding);
674 static void vnc_desktop_resize(VncState *vs)
676 if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
677 return;
679 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
680 vs->client_height == pixman_image_get_height(vs->vd->server)) {
681 return;
683 vs->client_width = pixman_image_get_width(vs->vd->server);
684 vs->client_height = pixman_image_get_height(vs->vd->server);
685 vnc_lock_output(vs);
686 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
687 vnc_write_u8(vs, 0);
688 vnc_write_u16(vs, 1); /* number of rects */
689 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
690 VNC_ENCODING_DESKTOPRESIZE);
691 vnc_unlock_output(vs);
692 vnc_flush(vs);
695 static void vnc_abort_display_jobs(VncDisplay *vd)
697 VncState *vs;
699 QTAILQ_FOREACH(vs, &vd->clients, next) {
700 vnc_lock_output(vs);
701 vs->abort = true;
702 vnc_unlock_output(vs);
704 QTAILQ_FOREACH(vs, &vd->clients, next) {
705 vnc_jobs_join(vs);
707 QTAILQ_FOREACH(vs, &vd->clients, next) {
708 vnc_lock_output(vs);
709 vs->abort = false;
710 vnc_unlock_output(vs);
714 int vnc_server_fb_stride(VncDisplay *vd)
716 return pixman_image_get_stride(vd->server);
719 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
721 uint8_t *ptr;
723 ptr = (uint8_t *)pixman_image_get_data(vd->server);
724 ptr += y * vnc_server_fb_stride(vd);
725 ptr += x * VNC_SERVER_FB_BYTES;
726 return ptr;
729 static void vnc_update_server_surface(VncDisplay *vd)
731 qemu_pixman_image_unref(vd->server);
732 vd->server = NULL;
734 if (QTAILQ_EMPTY(&vd->clients)) {
735 return;
738 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
739 vnc_width(vd),
740 vnc_height(vd),
741 NULL, 0);
744 static void vnc_dpy_switch(DisplayChangeListener *dcl,
745 DisplaySurface *surface)
747 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
748 VncState *vs;
749 int width, height;
751 vnc_abort_display_jobs(vd);
752 vd->ds = surface;
754 /* server surface */
755 vnc_update_server_surface(vd);
757 /* guest surface */
758 qemu_pixman_image_unref(vd->guest.fb);
759 vd->guest.fb = pixman_image_ref(surface->image);
760 vd->guest.format = surface->format;
761 width = vnc_width(vd);
762 height = vnc_height(vd);
763 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
764 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
765 width, height);
767 QTAILQ_FOREACH(vs, &vd->clients, next) {
768 vnc_colordepth(vs);
769 vnc_desktop_resize(vs);
770 if (vs->vd->cursor) {
771 vnc_cursor_define(vs);
773 memset(vs->dirty, 0x00, sizeof(vs->dirty));
774 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
775 width, height);
779 /* fastest code */
780 static void vnc_write_pixels_copy(VncState *vs,
781 void *pixels, int size)
783 vnc_write(vs, pixels, size);
786 /* slowest but generic code. */
787 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
789 uint8_t r, g, b;
791 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
792 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
793 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
794 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
795 #else
796 # error need some bits here if you change VNC_SERVER_FB_FORMAT
797 #endif
798 v = (r << vs->client_pf.rshift) |
799 (g << vs->client_pf.gshift) |
800 (b << vs->client_pf.bshift);
801 switch (vs->client_pf.bytes_per_pixel) {
802 case 1:
803 buf[0] = v;
804 break;
805 case 2:
806 if (vs->client_be) {
807 buf[0] = v >> 8;
808 buf[1] = v;
809 } else {
810 buf[1] = v >> 8;
811 buf[0] = v;
813 break;
814 default:
815 case 4:
816 if (vs->client_be) {
817 buf[0] = v >> 24;
818 buf[1] = v >> 16;
819 buf[2] = v >> 8;
820 buf[3] = v;
821 } else {
822 buf[3] = v >> 24;
823 buf[2] = v >> 16;
824 buf[1] = v >> 8;
825 buf[0] = v;
827 break;
831 static void vnc_write_pixels_generic(VncState *vs,
832 void *pixels1, int size)
834 uint8_t buf[4];
836 if (VNC_SERVER_FB_BYTES == 4) {
837 uint32_t *pixels = pixels1;
838 int n, i;
839 n = size >> 2;
840 for (i = 0; i < n; i++) {
841 vnc_convert_pixel(vs, buf, pixels[i]);
842 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
847 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
849 int i;
850 uint8_t *row;
851 VncDisplay *vd = vs->vd;
853 row = vnc_server_fb_ptr(vd, x, y);
854 for (i = 0; i < h; i++) {
855 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
856 row += vnc_server_fb_stride(vd);
858 return 1;
861 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
863 int n = 0;
864 bool encode_raw = false;
865 size_t saved_offs = vs->output.offset;
867 switch(vs->vnc_encoding) {
868 case VNC_ENCODING_ZLIB:
869 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
870 break;
871 case VNC_ENCODING_HEXTILE:
872 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
873 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
874 break;
875 case VNC_ENCODING_TIGHT:
876 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
877 break;
878 case VNC_ENCODING_TIGHT_PNG:
879 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
880 break;
881 case VNC_ENCODING_ZRLE:
882 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
883 break;
884 case VNC_ENCODING_ZYWRLE:
885 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
886 break;
887 default:
888 encode_raw = true;
889 break;
892 /* If the client has the same pixel format as our internal buffer and
893 * a RAW encoding would need less space fall back to RAW encoding to
894 * save bandwidth and processing power in the client. */
895 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
896 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
897 vs->output.offset = saved_offs;
898 encode_raw = true;
901 if (encode_raw) {
902 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
903 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
906 return n;
909 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
911 /* send bitblit op to the vnc client */
912 vnc_lock_output(vs);
913 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
914 vnc_write_u8(vs, 0);
915 vnc_write_u16(vs, 1); /* number of rects */
916 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
917 vnc_write_u16(vs, src_x);
918 vnc_write_u16(vs, src_y);
919 vnc_unlock_output(vs);
920 vnc_flush(vs);
923 static void vnc_dpy_copy(DisplayChangeListener *dcl,
924 int src_x, int src_y,
925 int dst_x, int dst_y, int w, int h)
927 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
928 VncState *vs, *vn;
929 uint8_t *src_row;
930 uint8_t *dst_row;
931 int i, x, y, pitch, inc, w_lim, s;
932 int cmp_bytes;
934 if (!vd->server) {
935 /* no client connected */
936 return;
939 vnc_refresh_server_surface(vd);
940 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
941 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
942 vs->force_update = 1;
943 vnc_update_client(vs, 1, true);
944 /* vs might be free()ed here */
948 /* do bitblit op on the local surface too */
949 pitch = vnc_server_fb_stride(vd);
950 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
951 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
952 y = dst_y;
953 inc = 1;
954 if (dst_y > src_y) {
955 /* copy backwards */
956 src_row += pitch * (h-1);
957 dst_row += pitch * (h-1);
958 pitch = -pitch;
959 y = dst_y + h - 1;
960 inc = -1;
962 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
963 if (w_lim < 0) {
964 w_lim = w;
965 } else {
966 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
968 for (i = 0; i < h; i++) {
969 for (x = 0; x <= w_lim;
970 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
971 if (x == w_lim) {
972 if ((s = w - w_lim) == 0)
973 break;
974 } else if (!x) {
975 s = (VNC_DIRTY_PIXELS_PER_BIT -
976 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
977 s = MIN(s, w_lim);
978 } else {
979 s = VNC_DIRTY_PIXELS_PER_BIT;
981 cmp_bytes = s * VNC_SERVER_FB_BYTES;
982 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
983 continue;
984 memmove(dst_row, src_row, cmp_bytes);
985 QTAILQ_FOREACH(vs, &vd->clients, next) {
986 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
987 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
988 vs->dirty[y]);
992 src_row += pitch - w * VNC_SERVER_FB_BYTES;
993 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
994 y += inc;
997 QTAILQ_FOREACH(vs, &vd->clients, next) {
998 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
999 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
1004 static void vnc_mouse_set(DisplayChangeListener *dcl,
1005 int x, int y, int visible)
1007 /* can we ask the client(s) to move the pointer ??? */
1010 static int vnc_cursor_define(VncState *vs)
1012 QEMUCursor *c = vs->vd->cursor;
1013 int isize;
1015 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
1016 vnc_lock_output(vs);
1017 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1018 vnc_write_u8(vs, 0); /* padding */
1019 vnc_write_u16(vs, 1); /* # of rects */
1020 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1021 VNC_ENCODING_RICH_CURSOR);
1022 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
1023 vnc_write_pixels_generic(vs, c->data, isize);
1024 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
1025 vnc_unlock_output(vs);
1026 return 0;
1028 return -1;
1031 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1032 QEMUCursor *c)
1034 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1035 VncState *vs;
1037 cursor_put(vd->cursor);
1038 g_free(vd->cursor_mask);
1040 vd->cursor = c;
1041 cursor_get(vd->cursor);
1042 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1043 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1044 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1046 QTAILQ_FOREACH(vs, &vd->clients, next) {
1047 vnc_cursor_define(vs);
1051 static int find_and_clear_dirty_height(VncState *vs,
1052 int y, int last_x, int x, int height)
1054 int h;
1056 for (h = 1; h < (height - y); h++) {
1057 if (!test_bit(last_x, vs->dirty[y + h])) {
1058 break;
1060 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1063 return h;
1066 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1068 vs->has_dirty += has_dirty;
1069 if (vs->need_update && vs->csock != -1) {
1070 VncDisplay *vd = vs->vd;
1071 VncJob *job;
1072 int y;
1073 int height, width;
1074 int n = 0;
1076 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1077 /* kernel send buffers are full -> drop frames to throttle */
1078 return 0;
1080 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1081 return 0;
1084 * Send screen updates to the vnc client using the server
1085 * surface and server dirty map. guest surface updates
1086 * happening in parallel don't disturb us, the next pass will
1087 * send them to the client.
1089 job = vnc_job_new(vs);
1091 height = pixman_image_get_height(vd->server);
1092 width = pixman_image_get_width(vd->server);
1094 y = 0;
1095 for (;;) {
1096 int x, h;
1097 unsigned long x2;
1098 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1099 height * VNC_DIRTY_BPL(vs),
1100 y * VNC_DIRTY_BPL(vs));
1101 if (offset == height * VNC_DIRTY_BPL(vs)) {
1102 /* no more dirty bits */
1103 break;
1105 y = offset / VNC_DIRTY_BPL(vs);
1106 x = offset % VNC_DIRTY_BPL(vs);
1107 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1108 VNC_DIRTY_BPL(vs), x);
1109 bitmap_clear(vs->dirty[y], x, x2 - x);
1110 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1111 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1112 if (x2 > x) {
1113 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1114 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1116 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1117 y += h;
1118 if (y == height) {
1119 break;
1124 vnc_job_push(job);
1125 if (sync) {
1126 vnc_jobs_join(vs);
1128 vs->force_update = 0;
1129 vs->has_dirty = 0;
1130 return n;
1133 if (vs->csock == -1) {
1134 vnc_disconnect_finish(vs);
1135 } else if (sync) {
1136 vnc_jobs_join(vs);
1139 return 0;
1142 /* audio */
1143 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1145 VncState *vs = opaque;
1147 switch (cmd) {
1148 case AUD_CNOTIFY_DISABLE:
1149 vnc_lock_output(vs);
1150 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1151 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1152 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1153 vnc_unlock_output(vs);
1154 vnc_flush(vs);
1155 break;
1157 case AUD_CNOTIFY_ENABLE:
1158 vnc_lock_output(vs);
1159 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1160 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1161 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1162 vnc_unlock_output(vs);
1163 vnc_flush(vs);
1164 break;
1168 static void audio_capture_destroy(void *opaque)
1172 static void audio_capture(void *opaque, void *buf, int size)
1174 VncState *vs = opaque;
1176 vnc_lock_output(vs);
1177 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1178 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1179 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1180 vnc_write_u32(vs, size);
1181 vnc_write(vs, buf, size);
1182 vnc_unlock_output(vs);
1183 vnc_flush(vs);
1186 static void audio_add(VncState *vs)
1188 struct audio_capture_ops ops;
1190 if (vs->audio_cap) {
1191 error_report("audio already running");
1192 return;
1195 ops.notify = audio_capture_notify;
1196 ops.destroy = audio_capture_destroy;
1197 ops.capture = audio_capture;
1199 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1200 if (!vs->audio_cap) {
1201 error_report("Failed to add audio capture");
1205 static void audio_del(VncState *vs)
1207 if (vs->audio_cap) {
1208 AUD_del_capture(vs->audio_cap, vs);
1209 vs->audio_cap = NULL;
1213 static void vnc_disconnect_start(VncState *vs)
1215 if (vs->csock == -1)
1216 return;
1217 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1218 qemu_set_fd_handler(vs->csock, NULL, NULL, NULL);
1219 closesocket(vs->csock);
1220 vs->csock = -1;
1223 void vnc_disconnect_finish(VncState *vs)
1225 int i;
1227 vnc_jobs_join(vs); /* Wait encoding jobs */
1229 vnc_lock_output(vs);
1230 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1232 buffer_free(&vs->input);
1233 buffer_free(&vs->output);
1234 buffer_free(&vs->ws_input);
1235 buffer_free(&vs->ws_output);
1237 qapi_free_VncClientInfo(vs->info);
1239 vnc_zlib_clear(vs);
1240 vnc_tight_clear(vs);
1241 vnc_zrle_clear(vs);
1243 qcrypto_tls_session_free(vs->tls);
1244 #ifdef CONFIG_VNC_SASL
1245 vnc_sasl_client_cleanup(vs);
1246 #endif /* CONFIG_VNC_SASL */
1247 audio_del(vs);
1248 vnc_release_modifiers(vs);
1250 if (vs->initialized) {
1251 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1252 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1253 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1254 /* last client gone */
1255 vnc_update_server_surface(vs->vd);
1259 if (vs->vd->lock_key_sync)
1260 qemu_remove_led_event_handler(vs->led);
1261 vnc_unlock_output(vs);
1263 qemu_mutex_destroy(&vs->output_mutex);
1264 if (vs->bh != NULL) {
1265 qemu_bh_delete(vs->bh);
1267 buffer_free(&vs->jobs_buffer);
1269 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1270 g_free(vs->lossy_rect[i]);
1272 g_free(vs->lossy_rect);
1273 g_free(vs);
1276 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, int last_errno)
1278 if (ret == 0 || ret == -1) {
1279 if (ret == -1) {
1280 switch (last_errno) {
1281 case EINTR:
1282 case EAGAIN:
1283 #ifdef _WIN32
1284 case WSAEWOULDBLOCK:
1285 #endif
1286 return 0;
1287 default:
1288 break;
1292 VNC_DEBUG("Closing down client sock: ret %zd, errno %d\n",
1293 ret, ret < 0 ? last_errno : 0);
1294 vnc_disconnect_start(vs);
1296 return 0;
1298 return ret;
1302 void vnc_client_error(VncState *vs)
1304 VNC_DEBUG("Closing down client sock: protocol error\n");
1305 vnc_disconnect_start(vs);
1309 ssize_t vnc_tls_pull(char *buf, size_t len, void *opaque)
1311 VncState *vs = opaque;
1312 ssize_t ret;
1314 retry:
1315 ret = qemu_recv(vs->csock, buf, len, 0);
1316 if (ret < 0) {
1317 if (errno == EINTR) {
1318 goto retry;
1320 return -1;
1322 return ret;
1326 ssize_t vnc_tls_push(const char *buf, size_t len, void *opaque)
1328 VncState *vs = opaque;
1329 ssize_t ret;
1331 retry:
1332 ret = send(vs->csock, buf, len, 0);
1333 if (ret < 0) {
1334 if (errno == EINTR) {
1335 goto retry;
1337 return -1;
1339 return ret;
1344 * Called to write a chunk of data to the client socket. The data may
1345 * be the raw data, or may have already been encoded by SASL.
1346 * The data will be written either straight onto the socket, or
1347 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1349 * NB, it is theoretically possible to have 2 layers of encryption,
1350 * both SASL, and this TLS layer. It is highly unlikely in practice
1351 * though, since SASL encryption will typically be a no-op if TLS
1352 * is active
1354 * Returns the number of bytes written, which may be less than
1355 * the requested 'datalen' if the socket would block. Returns
1356 * -1 on error, and disconnects the client socket.
1358 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1360 ssize_t ret;
1361 int err = 0;
1362 if (vs->tls) {
1363 ret = qcrypto_tls_session_write(vs->tls, (const char *)data, datalen);
1364 if (ret < 0) {
1365 err = errno;
1367 } else {
1368 ret = send(vs->csock, (const void *)data, datalen, 0);
1369 if (ret < 0) {
1370 err = socket_error();
1373 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1374 return vnc_client_io_error(vs, ret, err);
1379 * Called to write buffered data to the client socket, when not
1380 * using any SASL SSF encryption layers. Will write as much data
1381 * as possible without blocking. If all buffered data is written,
1382 * will switch the FD poll() handler back to read monitoring.
1384 * Returns the number of bytes written, which may be less than
1385 * the buffered output data if the socket would block. Returns
1386 * -1 on error, and disconnects the client socket.
1388 static ssize_t vnc_client_write_plain(VncState *vs)
1390 ssize_t ret;
1392 #ifdef CONFIG_VNC_SASL
1393 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1394 vs->output.buffer, vs->output.capacity, vs->output.offset,
1395 vs->sasl.waitWriteSSF);
1397 if (vs->sasl.conn &&
1398 vs->sasl.runSSF &&
1399 vs->sasl.waitWriteSSF) {
1400 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1401 if (ret)
1402 vs->sasl.waitWriteSSF -= ret;
1403 } else
1404 #endif /* CONFIG_VNC_SASL */
1405 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1406 if (!ret)
1407 return 0;
1409 buffer_advance(&vs->output, ret);
1411 if (vs->output.offset == 0) {
1412 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
1415 return ret;
1420 * First function called whenever there is data to be written to
1421 * the client socket. Will delegate actual work according to whether
1422 * SASL SSF layers are enabled (thus requiring encryption calls)
1424 static void vnc_client_write_locked(void *opaque)
1426 VncState *vs = opaque;
1428 #ifdef CONFIG_VNC_SASL
1429 if (vs->sasl.conn &&
1430 vs->sasl.runSSF &&
1431 !vs->sasl.waitWriteSSF) {
1432 vnc_client_write_sasl(vs);
1433 } else
1434 #endif /* CONFIG_VNC_SASL */
1436 if (vs->encode_ws) {
1437 vnc_client_write_ws(vs);
1438 } else {
1439 vnc_client_write_plain(vs);
1444 void vnc_client_write(void *opaque)
1446 VncState *vs = opaque;
1448 vnc_lock_output(vs);
1449 if (vs->output.offset || vs->ws_output.offset) {
1450 vnc_client_write_locked(opaque);
1451 } else if (vs->csock != -1) {
1452 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
1454 vnc_unlock_output(vs);
1457 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1459 vs->read_handler = func;
1460 vs->read_handler_expect = expecting;
1465 * Called to read a chunk of data from the client socket. The data may
1466 * be the raw data, or may need to be further decoded by SASL.
1467 * The data will be read either straight from to the socket, or
1468 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1470 * NB, it is theoretically possible to have 2 layers of encryption,
1471 * both SASL, and this TLS layer. It is highly unlikely in practice
1472 * though, since SASL encryption will typically be a no-op if TLS
1473 * is active
1475 * Returns the number of bytes read, which may be less than
1476 * the requested 'datalen' if the socket would block. Returns
1477 * -1 on error, and disconnects the client socket.
1479 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1481 ssize_t ret;
1482 int err = -1;
1483 if (vs->tls) {
1484 ret = qcrypto_tls_session_read(vs->tls, (char *)data, datalen);
1485 if (ret < 0) {
1486 err = errno;
1488 } else {
1489 ret = qemu_recv(vs->csock, data, datalen, 0);
1490 if (ret < 0) {
1491 err = socket_error();
1494 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1495 return vnc_client_io_error(vs, ret, err);
1500 * Called to read data from the client socket to the input buffer,
1501 * when not using any SASL SSF encryption layers. Will read as much
1502 * data as possible without blocking.
1504 * Returns the number of bytes read. Returns -1 on error, and
1505 * disconnects the client socket.
1507 static ssize_t vnc_client_read_plain(VncState *vs)
1509 ssize_t ret;
1510 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1511 vs->input.buffer, vs->input.capacity, vs->input.offset);
1512 buffer_reserve(&vs->input, 4096);
1513 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1514 if (!ret)
1515 return 0;
1516 vs->input.offset += ret;
1517 return ret;
1520 static void vnc_jobs_bh(void *opaque)
1522 VncState *vs = opaque;
1524 vnc_jobs_consume_buffer(vs);
1528 * First function called whenever there is more data to be read from
1529 * the client socket. Will delegate actual work according to whether
1530 * SASL SSF layers are enabled (thus requiring decryption calls)
1532 void vnc_client_read(void *opaque)
1534 VncState *vs = opaque;
1535 ssize_t ret;
1537 #ifdef CONFIG_VNC_SASL
1538 if (vs->sasl.conn && vs->sasl.runSSF)
1539 ret = vnc_client_read_sasl(vs);
1540 else
1541 #endif /* CONFIG_VNC_SASL */
1542 if (vs->encode_ws) {
1543 ret = vnc_client_read_ws(vs);
1544 if (ret == -1) {
1545 vnc_disconnect_start(vs);
1546 return;
1547 } else if (ret == -2) {
1548 vnc_client_error(vs);
1549 return;
1551 } else {
1552 ret = vnc_client_read_plain(vs);
1554 if (!ret) {
1555 if (vs->csock == -1)
1556 vnc_disconnect_finish(vs);
1557 return;
1560 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1561 size_t len = vs->read_handler_expect;
1562 int ret;
1564 ret = vs->read_handler(vs, vs->input.buffer, len);
1565 if (vs->csock == -1) {
1566 vnc_disconnect_finish(vs);
1567 return;
1570 if (!ret) {
1571 buffer_advance(&vs->input, len);
1572 } else {
1573 vs->read_handler_expect = ret;
1578 void vnc_write(VncState *vs, const void *data, size_t len)
1580 buffer_reserve(&vs->output, len);
1582 if (vs->csock != -1 && buffer_empty(&vs->output)) {
1583 qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs);
1586 buffer_append(&vs->output, data, len);
1589 void vnc_write_s32(VncState *vs, int32_t value)
1591 vnc_write_u32(vs, *(uint32_t *)&value);
1594 void vnc_write_u32(VncState *vs, uint32_t value)
1596 uint8_t buf[4];
1598 buf[0] = (value >> 24) & 0xFF;
1599 buf[1] = (value >> 16) & 0xFF;
1600 buf[2] = (value >> 8) & 0xFF;
1601 buf[3] = value & 0xFF;
1603 vnc_write(vs, buf, 4);
1606 void vnc_write_u16(VncState *vs, uint16_t value)
1608 uint8_t buf[2];
1610 buf[0] = (value >> 8) & 0xFF;
1611 buf[1] = value & 0xFF;
1613 vnc_write(vs, buf, 2);
1616 void vnc_write_u8(VncState *vs, uint8_t value)
1618 vnc_write(vs, (char *)&value, 1);
1621 void vnc_flush(VncState *vs)
1623 vnc_lock_output(vs);
1624 if (vs->csock != -1 && (vs->output.offset ||
1625 vs->ws_output.offset)) {
1626 vnc_client_write_locked(vs);
1628 vnc_unlock_output(vs);
1631 static uint8_t read_u8(uint8_t *data, size_t offset)
1633 return data[offset];
1636 static uint16_t read_u16(uint8_t *data, size_t offset)
1638 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1641 static int32_t read_s32(uint8_t *data, size_t offset)
1643 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1644 (data[offset + 2] << 8) | data[offset + 3]);
1647 uint32_t read_u32(uint8_t *data, size_t offset)
1649 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1650 (data[offset + 2] << 8) | data[offset + 3]);
1653 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1657 static void check_pointer_type_change(Notifier *notifier, void *data)
1659 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1660 int absolute = qemu_input_is_absolute();
1662 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1663 vnc_lock_output(vs);
1664 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1665 vnc_write_u8(vs, 0);
1666 vnc_write_u16(vs, 1);
1667 vnc_framebuffer_update(vs, absolute, 0,
1668 pixman_image_get_width(vs->vd->server),
1669 pixman_image_get_height(vs->vd->server),
1670 VNC_ENCODING_POINTER_TYPE_CHANGE);
1671 vnc_unlock_output(vs);
1672 vnc_flush(vs);
1674 vs->absolute = absolute;
1677 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1679 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1680 [INPUT_BUTTON_LEFT] = 0x01,
1681 [INPUT_BUTTON_MIDDLE] = 0x02,
1682 [INPUT_BUTTON_RIGHT] = 0x04,
1683 [INPUT_BUTTON_WHEELUP] = 0x08,
1684 [INPUT_BUTTON_WHEELDOWN] = 0x10,
1686 QemuConsole *con = vs->vd->dcl.con;
1687 int width = pixman_image_get_width(vs->vd->server);
1688 int height = pixman_image_get_height(vs->vd->server);
1690 if (vs->last_bmask != button_mask) {
1691 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1692 vs->last_bmask = button_mask;
1695 if (vs->absolute) {
1696 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1697 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1698 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1699 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1700 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1701 } else {
1702 if (vs->last_x != -1) {
1703 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1704 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1706 vs->last_x = x;
1707 vs->last_y = y;
1709 qemu_input_event_sync();
1712 static void reset_keys(VncState *vs)
1714 int i;
1715 for(i = 0; i < 256; i++) {
1716 if (vs->modifiers_state[i]) {
1717 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1718 vs->modifiers_state[i] = 0;
1723 static void press_key(VncState *vs, int keysym)
1725 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1726 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1727 qemu_input_event_send_key_delay(0);
1728 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1729 qemu_input_event_send_key_delay(0);
1732 static int current_led_state(VncState *vs)
1734 int ledstate = 0;
1736 if (vs->modifiers_state[0x46]) {
1737 ledstate |= QEMU_SCROLL_LOCK_LED;
1739 if (vs->modifiers_state[0x45]) {
1740 ledstate |= QEMU_NUM_LOCK_LED;
1742 if (vs->modifiers_state[0x3a]) {
1743 ledstate |= QEMU_CAPS_LOCK_LED;
1746 return ledstate;
1749 static void vnc_led_state_change(VncState *vs)
1751 int ledstate = 0;
1753 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1754 return;
1757 ledstate = current_led_state(vs);
1758 vnc_lock_output(vs);
1759 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1760 vnc_write_u8(vs, 0);
1761 vnc_write_u16(vs, 1);
1762 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1763 vnc_write_u8(vs, ledstate);
1764 vnc_unlock_output(vs);
1765 vnc_flush(vs);
1768 static void kbd_leds(void *opaque, int ledstate)
1770 VncState *vs = opaque;
1771 int caps, num, scr;
1772 bool has_changed = (ledstate != current_led_state(vs));
1774 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1775 (ledstate & QEMU_NUM_LOCK_LED),
1776 (ledstate & QEMU_SCROLL_LOCK_LED));
1778 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1779 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1780 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1782 if (vs->modifiers_state[0x3a] != caps) {
1783 vs->modifiers_state[0x3a] = caps;
1785 if (vs->modifiers_state[0x45] != num) {
1786 vs->modifiers_state[0x45] = num;
1788 if (vs->modifiers_state[0x46] != scr) {
1789 vs->modifiers_state[0x46] = scr;
1792 /* Sending the current led state message to the client */
1793 if (has_changed) {
1794 vnc_led_state_change(vs);
1798 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1800 /* QEMU console switch */
1801 switch(keycode) {
1802 case 0x2a: /* Left Shift */
1803 case 0x36: /* Right Shift */
1804 case 0x1d: /* Left CTRL */
1805 case 0x9d: /* Right CTRL */
1806 case 0x38: /* Left ALT */
1807 case 0xb8: /* Right ALT */
1808 if (down)
1809 vs->modifiers_state[keycode] = 1;
1810 else
1811 vs->modifiers_state[keycode] = 0;
1812 break;
1813 case 0x02 ... 0x0a: /* '1' to '9' keys */
1814 if (vs->vd->dcl.con == NULL &&
1815 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1816 /* Reset the modifiers sent to the current console */
1817 reset_keys(vs);
1818 console_select(keycode - 0x02);
1819 return;
1821 break;
1822 case 0x3a: /* CapsLock */
1823 case 0x45: /* NumLock */
1824 if (down)
1825 vs->modifiers_state[keycode] ^= 1;
1826 break;
1829 /* Turn off the lock state sync logic if the client support the led
1830 state extension.
1832 if (down && vs->vd->lock_key_sync &&
1833 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1834 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1835 /* If the numlock state needs to change then simulate an additional
1836 keypress before sending this one. This will happen if the user
1837 toggles numlock away from the VNC window.
1839 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1840 if (!vs->modifiers_state[0x45]) {
1841 trace_vnc_key_sync_numlock(true);
1842 vs->modifiers_state[0x45] = 1;
1843 press_key(vs, 0xff7f);
1845 } else {
1846 if (vs->modifiers_state[0x45]) {
1847 trace_vnc_key_sync_numlock(false);
1848 vs->modifiers_state[0x45] = 0;
1849 press_key(vs, 0xff7f);
1854 if (down && vs->vd->lock_key_sync &&
1855 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1856 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1857 /* If the capslock state needs to change then simulate an additional
1858 keypress before sending this one. This will happen if the user
1859 toggles capslock away from the VNC window.
1861 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1862 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1863 int capslock = !!(vs->modifiers_state[0x3a]);
1864 if (capslock) {
1865 if (uppercase == shift) {
1866 trace_vnc_key_sync_capslock(false);
1867 vs->modifiers_state[0x3a] = 0;
1868 press_key(vs, 0xffe5);
1870 } else {
1871 if (uppercase != shift) {
1872 trace_vnc_key_sync_capslock(true);
1873 vs->modifiers_state[0x3a] = 1;
1874 press_key(vs, 0xffe5);
1879 if (qemu_console_is_graphic(NULL)) {
1880 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1881 } else {
1882 bool numlock = vs->modifiers_state[0x45];
1883 bool control = (vs->modifiers_state[0x1d] ||
1884 vs->modifiers_state[0x9d]);
1885 /* QEMU console emulation */
1886 if (down) {
1887 switch (keycode) {
1888 case 0x2a: /* Left Shift */
1889 case 0x36: /* Right Shift */
1890 case 0x1d: /* Left CTRL */
1891 case 0x9d: /* Right CTRL */
1892 case 0x38: /* Left ALT */
1893 case 0xb8: /* Right ALT */
1894 break;
1895 case 0xc8:
1896 kbd_put_keysym(QEMU_KEY_UP);
1897 break;
1898 case 0xd0:
1899 kbd_put_keysym(QEMU_KEY_DOWN);
1900 break;
1901 case 0xcb:
1902 kbd_put_keysym(QEMU_KEY_LEFT);
1903 break;
1904 case 0xcd:
1905 kbd_put_keysym(QEMU_KEY_RIGHT);
1906 break;
1907 case 0xd3:
1908 kbd_put_keysym(QEMU_KEY_DELETE);
1909 break;
1910 case 0xc7:
1911 kbd_put_keysym(QEMU_KEY_HOME);
1912 break;
1913 case 0xcf:
1914 kbd_put_keysym(QEMU_KEY_END);
1915 break;
1916 case 0xc9:
1917 kbd_put_keysym(QEMU_KEY_PAGEUP);
1918 break;
1919 case 0xd1:
1920 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1921 break;
1923 case 0x47:
1924 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1925 break;
1926 case 0x48:
1927 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1928 break;
1929 case 0x49:
1930 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1931 break;
1932 case 0x4b:
1933 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1934 break;
1935 case 0x4c:
1936 kbd_put_keysym('5');
1937 break;
1938 case 0x4d:
1939 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1940 break;
1941 case 0x4f:
1942 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1943 break;
1944 case 0x50:
1945 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1946 break;
1947 case 0x51:
1948 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1949 break;
1950 case 0x52:
1951 kbd_put_keysym('0');
1952 break;
1953 case 0x53:
1954 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1955 break;
1957 case 0xb5:
1958 kbd_put_keysym('/');
1959 break;
1960 case 0x37:
1961 kbd_put_keysym('*');
1962 break;
1963 case 0x4a:
1964 kbd_put_keysym('-');
1965 break;
1966 case 0x4e:
1967 kbd_put_keysym('+');
1968 break;
1969 case 0x9c:
1970 kbd_put_keysym('\n');
1971 break;
1973 default:
1974 if (control) {
1975 kbd_put_keysym(sym & 0x1f);
1976 } else {
1977 kbd_put_keysym(sym);
1979 break;
1985 static void vnc_release_modifiers(VncState *vs)
1987 static const int keycodes[] = {
1988 /* shift, control, alt keys, both left & right */
1989 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1991 int i, keycode;
1993 if (!qemu_console_is_graphic(NULL)) {
1994 return;
1996 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1997 keycode = keycodes[i];
1998 if (!vs->modifiers_state[keycode]) {
1999 continue;
2001 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
2005 static const char *code2name(int keycode)
2007 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
2010 static void key_event(VncState *vs, int down, uint32_t sym)
2012 int keycode;
2013 int lsym = sym;
2015 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2016 lsym = lsym - 'A' + 'a';
2019 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
2020 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2021 do_key_event(vs, down, keycode, sym);
2024 static void ext_key_event(VncState *vs, int down,
2025 uint32_t sym, uint16_t keycode)
2027 /* if the user specifies a keyboard layout, always use it */
2028 if (keyboard_layout) {
2029 key_event(vs, down, sym);
2030 } else {
2031 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2032 do_key_event(vs, down, keycode, sym);
2036 static void framebuffer_update_request(VncState *vs, int incremental,
2037 int x, int y, int w, int h)
2039 vs->need_update = 1;
2041 if (incremental) {
2042 return;
2045 vs->force_update = 1;
2046 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
2049 static void send_ext_key_event_ack(VncState *vs)
2051 vnc_lock_output(vs);
2052 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2053 vnc_write_u8(vs, 0);
2054 vnc_write_u16(vs, 1);
2055 vnc_framebuffer_update(vs, 0, 0,
2056 pixman_image_get_width(vs->vd->server),
2057 pixman_image_get_height(vs->vd->server),
2058 VNC_ENCODING_EXT_KEY_EVENT);
2059 vnc_unlock_output(vs);
2060 vnc_flush(vs);
2063 static void send_ext_audio_ack(VncState *vs)
2065 vnc_lock_output(vs);
2066 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2067 vnc_write_u8(vs, 0);
2068 vnc_write_u16(vs, 1);
2069 vnc_framebuffer_update(vs, 0, 0,
2070 pixman_image_get_width(vs->vd->server),
2071 pixman_image_get_height(vs->vd->server),
2072 VNC_ENCODING_AUDIO);
2073 vnc_unlock_output(vs);
2074 vnc_flush(vs);
2077 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2079 int i;
2080 unsigned int enc = 0;
2082 vs->features = 0;
2083 vs->vnc_encoding = 0;
2084 vs->tight.compression = 9;
2085 vs->tight.quality = -1; /* Lossless by default */
2086 vs->absolute = -1;
2089 * Start from the end because the encodings are sent in order of preference.
2090 * This way the preferred encoding (first encoding defined in the array)
2091 * will be set at the end of the loop.
2093 for (i = n_encodings - 1; i >= 0; i--) {
2094 enc = encodings[i];
2095 switch (enc) {
2096 case VNC_ENCODING_RAW:
2097 vs->vnc_encoding = enc;
2098 break;
2099 case VNC_ENCODING_COPYRECT:
2100 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2101 break;
2102 case VNC_ENCODING_HEXTILE:
2103 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2104 vs->vnc_encoding = enc;
2105 break;
2106 case VNC_ENCODING_TIGHT:
2107 vs->features |= VNC_FEATURE_TIGHT_MASK;
2108 vs->vnc_encoding = enc;
2109 break;
2110 #ifdef CONFIG_VNC_PNG
2111 case VNC_ENCODING_TIGHT_PNG:
2112 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2113 vs->vnc_encoding = enc;
2114 break;
2115 #endif
2116 case VNC_ENCODING_ZLIB:
2117 vs->features |= VNC_FEATURE_ZLIB_MASK;
2118 vs->vnc_encoding = enc;
2119 break;
2120 case VNC_ENCODING_ZRLE:
2121 vs->features |= VNC_FEATURE_ZRLE_MASK;
2122 vs->vnc_encoding = enc;
2123 break;
2124 case VNC_ENCODING_ZYWRLE:
2125 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2126 vs->vnc_encoding = enc;
2127 break;
2128 case VNC_ENCODING_DESKTOPRESIZE:
2129 vs->features |= VNC_FEATURE_RESIZE_MASK;
2130 break;
2131 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2132 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2133 break;
2134 case VNC_ENCODING_RICH_CURSOR:
2135 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2136 break;
2137 case VNC_ENCODING_EXT_KEY_EVENT:
2138 send_ext_key_event_ack(vs);
2139 break;
2140 case VNC_ENCODING_AUDIO:
2141 send_ext_audio_ack(vs);
2142 break;
2143 case VNC_ENCODING_WMVi:
2144 vs->features |= VNC_FEATURE_WMVI_MASK;
2145 break;
2146 case VNC_ENCODING_LED_STATE:
2147 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2148 break;
2149 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2150 vs->tight.compression = (enc & 0x0F);
2151 break;
2152 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2153 if (vs->vd->lossy) {
2154 vs->tight.quality = (enc & 0x0F);
2156 break;
2157 default:
2158 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2159 break;
2162 vnc_desktop_resize(vs);
2163 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2164 vnc_led_state_change(vs);
2167 static void set_pixel_conversion(VncState *vs)
2169 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2171 if (fmt == VNC_SERVER_FB_FORMAT) {
2172 vs->write_pixels = vnc_write_pixels_copy;
2173 vnc_hextile_set_pixel_conversion(vs, 0);
2174 } else {
2175 vs->write_pixels = vnc_write_pixels_generic;
2176 vnc_hextile_set_pixel_conversion(vs, 1);
2180 static void set_pixel_format(VncState *vs,
2181 int bits_per_pixel, int depth,
2182 int big_endian_flag, int true_color_flag,
2183 int red_max, int green_max, int blue_max,
2184 int red_shift, int green_shift, int blue_shift)
2186 if (!true_color_flag) {
2187 vnc_client_error(vs);
2188 return;
2191 switch (bits_per_pixel) {
2192 case 8:
2193 case 16:
2194 case 32:
2195 break;
2196 default:
2197 vnc_client_error(vs);
2198 return;
2201 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2202 vs->client_pf.rbits = hweight_long(red_max);
2203 vs->client_pf.rshift = red_shift;
2204 vs->client_pf.rmask = red_max << red_shift;
2205 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2206 vs->client_pf.gbits = hweight_long(green_max);
2207 vs->client_pf.gshift = green_shift;
2208 vs->client_pf.gmask = green_max << green_shift;
2209 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2210 vs->client_pf.bbits = hweight_long(blue_max);
2211 vs->client_pf.bshift = blue_shift;
2212 vs->client_pf.bmask = blue_max << blue_shift;
2213 vs->client_pf.bits_per_pixel = bits_per_pixel;
2214 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2215 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2216 vs->client_be = big_endian_flag;
2218 set_pixel_conversion(vs);
2220 graphic_hw_invalidate(vs->vd->dcl.con);
2221 graphic_hw_update(vs->vd->dcl.con);
2224 static void pixel_format_message (VncState *vs) {
2225 char pad[3] = { 0, 0, 0 };
2227 vs->client_pf = qemu_default_pixelformat(32);
2229 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2230 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2232 #ifdef HOST_WORDS_BIGENDIAN
2233 vnc_write_u8(vs, 1); /* big-endian-flag */
2234 #else
2235 vnc_write_u8(vs, 0); /* big-endian-flag */
2236 #endif
2237 vnc_write_u8(vs, 1); /* true-color-flag */
2238 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2239 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2240 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2241 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2242 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2243 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2244 vnc_write(vs, pad, 3); /* padding */
2246 vnc_hextile_set_pixel_conversion(vs, 0);
2247 vs->write_pixels = vnc_write_pixels_copy;
2250 static void vnc_colordepth(VncState *vs)
2252 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2253 /* Sending a WMVi message to notify the client*/
2254 vnc_lock_output(vs);
2255 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2256 vnc_write_u8(vs, 0);
2257 vnc_write_u16(vs, 1); /* number of rects */
2258 vnc_framebuffer_update(vs, 0, 0,
2259 pixman_image_get_width(vs->vd->server),
2260 pixman_image_get_height(vs->vd->server),
2261 VNC_ENCODING_WMVi);
2262 pixel_format_message(vs);
2263 vnc_unlock_output(vs);
2264 vnc_flush(vs);
2265 } else {
2266 set_pixel_conversion(vs);
2270 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2272 int i;
2273 uint16_t limit;
2274 VncDisplay *vd = vs->vd;
2276 if (data[0] > 3) {
2277 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2280 switch (data[0]) {
2281 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2282 if (len == 1)
2283 return 20;
2285 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2286 read_u8(data, 6), read_u8(data, 7),
2287 read_u16(data, 8), read_u16(data, 10),
2288 read_u16(data, 12), read_u8(data, 14),
2289 read_u8(data, 15), read_u8(data, 16));
2290 break;
2291 case VNC_MSG_CLIENT_SET_ENCODINGS:
2292 if (len == 1)
2293 return 4;
2295 if (len == 4) {
2296 limit = read_u16(data, 2);
2297 if (limit > 0)
2298 return 4 + (limit * 4);
2299 } else
2300 limit = read_u16(data, 2);
2302 for (i = 0; i < limit; i++) {
2303 int32_t val = read_s32(data, 4 + (i * 4));
2304 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2307 set_encodings(vs, (int32_t *)(data + 4), limit);
2308 break;
2309 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2310 if (len == 1)
2311 return 10;
2313 framebuffer_update_request(vs,
2314 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2315 read_u16(data, 6), read_u16(data, 8));
2316 break;
2317 case VNC_MSG_CLIENT_KEY_EVENT:
2318 if (len == 1)
2319 return 8;
2321 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2322 break;
2323 case VNC_MSG_CLIENT_POINTER_EVENT:
2324 if (len == 1)
2325 return 6;
2327 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2328 break;
2329 case VNC_MSG_CLIENT_CUT_TEXT:
2330 if (len == 1) {
2331 return 8;
2333 if (len == 8) {
2334 uint32_t dlen = read_u32(data, 4);
2335 if (dlen > (1 << 20)) {
2336 error_report("vnc: client_cut_text msg payload has %u bytes"
2337 " which exceeds our limit of 1MB.", dlen);
2338 vnc_client_error(vs);
2339 break;
2341 if (dlen > 0) {
2342 return 8 + dlen;
2346 client_cut_text(vs, read_u32(data, 4), data + 8);
2347 break;
2348 case VNC_MSG_CLIENT_QEMU:
2349 if (len == 1)
2350 return 2;
2352 switch (read_u8(data, 1)) {
2353 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2354 if (len == 2)
2355 return 12;
2357 ext_key_event(vs, read_u16(data, 2),
2358 read_u32(data, 4), read_u32(data, 8));
2359 break;
2360 case VNC_MSG_CLIENT_QEMU_AUDIO:
2361 if (len == 2)
2362 return 4;
2364 switch (read_u16 (data, 2)) {
2365 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2366 audio_add(vs);
2367 break;
2368 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2369 audio_del(vs);
2370 break;
2371 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2372 if (len == 4)
2373 return 10;
2374 switch (read_u8(data, 4)) {
2375 case 0: vs->as.fmt = AUD_FMT_U8; break;
2376 case 1: vs->as.fmt = AUD_FMT_S8; break;
2377 case 2: vs->as.fmt = AUD_FMT_U16; break;
2378 case 3: vs->as.fmt = AUD_FMT_S16; break;
2379 case 4: vs->as.fmt = AUD_FMT_U32; break;
2380 case 5: vs->as.fmt = AUD_FMT_S32; break;
2381 default:
2382 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2383 vnc_client_error(vs);
2384 break;
2386 vs->as.nchannels = read_u8(data, 5);
2387 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2388 VNC_DEBUG("Invalid audio channel coount %d\n",
2389 read_u8(data, 5));
2390 vnc_client_error(vs);
2391 break;
2393 vs->as.freq = read_u32(data, 6);
2394 break;
2395 default:
2396 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2397 vnc_client_error(vs);
2398 break;
2400 break;
2402 default:
2403 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2404 vnc_client_error(vs);
2405 break;
2407 break;
2408 default:
2409 VNC_DEBUG("Msg: %d\n", data[0]);
2410 vnc_client_error(vs);
2411 break;
2414 vnc_read_when(vs, protocol_client_msg, 1);
2415 return 0;
2418 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2420 char buf[1024];
2421 VncShareMode mode;
2422 int size;
2424 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2425 switch (vs->vd->share_policy) {
2426 case VNC_SHARE_POLICY_IGNORE:
2428 * Ignore the shared flag. Nothing to do here.
2430 * Doesn't conform to the rfb spec but is traditional qemu
2431 * behavior, thus left here as option for compatibility
2432 * reasons.
2434 break;
2435 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2437 * Policy: Allow clients ask for exclusive access.
2439 * Implementation: When a client asks for exclusive access,
2440 * disconnect all others. Shared connects are allowed as long
2441 * as no exclusive connection exists.
2443 * This is how the rfb spec suggests to handle the shared flag.
2445 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2446 VncState *client;
2447 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2448 if (vs == client) {
2449 continue;
2451 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2452 client->share_mode != VNC_SHARE_MODE_SHARED) {
2453 continue;
2455 vnc_disconnect_start(client);
2458 if (mode == VNC_SHARE_MODE_SHARED) {
2459 if (vs->vd->num_exclusive > 0) {
2460 vnc_disconnect_start(vs);
2461 return 0;
2464 break;
2465 case VNC_SHARE_POLICY_FORCE_SHARED:
2467 * Policy: Shared connects only.
2468 * Implementation: Disallow clients asking for exclusive access.
2470 * Useful for shared desktop sessions where you don't want
2471 * someone forgetting to say -shared when running the vnc
2472 * client disconnect everybody else.
2474 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2475 vnc_disconnect_start(vs);
2476 return 0;
2478 break;
2480 vnc_set_share_mode(vs, mode);
2482 if (vs->vd->num_shared > vs->vd->connections_limit) {
2483 vnc_disconnect_start(vs);
2484 return 0;
2487 vs->client_width = pixman_image_get_width(vs->vd->server);
2488 vs->client_height = pixman_image_get_height(vs->vd->server);
2489 vnc_write_u16(vs, vs->client_width);
2490 vnc_write_u16(vs, vs->client_height);
2492 pixel_format_message(vs);
2494 if (qemu_name)
2495 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2496 else
2497 size = snprintf(buf, sizeof(buf), "QEMU");
2499 vnc_write_u32(vs, size);
2500 vnc_write(vs, buf, size);
2501 vnc_flush(vs);
2503 vnc_client_cache_auth(vs);
2504 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2506 vnc_read_when(vs, protocol_client_msg, 1);
2508 return 0;
2511 void start_client_init(VncState *vs)
2513 vnc_read_when(vs, protocol_client_init, 1);
2516 static void make_challenge(VncState *vs)
2518 int i;
2520 srand(time(NULL)+getpid()+getpid()*987654+rand());
2522 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2523 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2526 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2528 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2529 size_t i, pwlen;
2530 unsigned char key[8];
2531 time_t now = time(NULL);
2532 QCryptoCipher *cipher = NULL;
2533 Error *err = NULL;
2535 if (!vs->vd->password) {
2536 VNC_DEBUG("No password configured on server");
2537 goto reject;
2539 if (vs->vd->expires < now) {
2540 VNC_DEBUG("Password is expired");
2541 goto reject;
2544 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2546 /* Calculate the expected challenge response */
2547 pwlen = strlen(vs->vd->password);
2548 for (i=0; i<sizeof(key); i++)
2549 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2551 cipher = qcrypto_cipher_new(
2552 QCRYPTO_CIPHER_ALG_DES_RFB,
2553 QCRYPTO_CIPHER_MODE_ECB,
2554 key, G_N_ELEMENTS(key),
2555 &err);
2556 if (!cipher) {
2557 VNC_DEBUG("Cannot initialize cipher %s",
2558 error_get_pretty(err));
2559 error_free(err);
2560 goto reject;
2563 if (qcrypto_cipher_encrypt(cipher,
2564 vs->challenge,
2565 response,
2566 VNC_AUTH_CHALLENGE_SIZE,
2567 &err) < 0) {
2568 VNC_DEBUG("Cannot encrypt challenge %s",
2569 error_get_pretty(err));
2570 error_free(err);
2571 goto reject;
2574 /* Compare expected vs actual challenge response */
2575 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2576 VNC_DEBUG("Client challenge response did not match\n");
2577 goto reject;
2578 } else {
2579 VNC_DEBUG("Accepting VNC challenge response\n");
2580 vnc_write_u32(vs, 0); /* Accept auth */
2581 vnc_flush(vs);
2583 start_client_init(vs);
2586 qcrypto_cipher_free(cipher);
2587 return 0;
2589 reject:
2590 vnc_write_u32(vs, 1); /* Reject auth */
2591 if (vs->minor >= 8) {
2592 static const char err[] = "Authentication failed";
2593 vnc_write_u32(vs, sizeof(err));
2594 vnc_write(vs, err, sizeof(err));
2596 vnc_flush(vs);
2597 vnc_client_error(vs);
2598 qcrypto_cipher_free(cipher);
2599 return 0;
2602 void start_auth_vnc(VncState *vs)
2604 make_challenge(vs);
2605 /* Send client a 'random' challenge */
2606 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2607 vnc_flush(vs);
2609 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2613 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2615 /* We only advertise 1 auth scheme at a time, so client
2616 * must pick the one we sent. Verify this */
2617 if (data[0] != vs->auth) { /* Reject auth */
2618 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2619 vnc_write_u32(vs, 1);
2620 if (vs->minor >= 8) {
2621 static const char err[] = "Authentication failed";
2622 vnc_write_u32(vs, sizeof(err));
2623 vnc_write(vs, err, sizeof(err));
2625 vnc_client_error(vs);
2626 } else { /* Accept requested auth */
2627 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2628 switch (vs->auth) {
2629 case VNC_AUTH_NONE:
2630 VNC_DEBUG("Accept auth none\n");
2631 if (vs->minor >= 8) {
2632 vnc_write_u32(vs, 0); /* Accept auth completion */
2633 vnc_flush(vs);
2635 start_client_init(vs);
2636 break;
2638 case VNC_AUTH_VNC:
2639 VNC_DEBUG("Start VNC auth\n");
2640 start_auth_vnc(vs);
2641 break;
2643 case VNC_AUTH_VENCRYPT:
2644 VNC_DEBUG("Accept VeNCrypt auth\n");
2645 start_auth_vencrypt(vs);
2646 break;
2648 #ifdef CONFIG_VNC_SASL
2649 case VNC_AUTH_SASL:
2650 VNC_DEBUG("Accept SASL auth\n");
2651 start_auth_sasl(vs);
2652 break;
2653 #endif /* CONFIG_VNC_SASL */
2655 default: /* Should not be possible, but just in case */
2656 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2657 vnc_write_u8(vs, 1);
2658 if (vs->minor >= 8) {
2659 static const char err[] = "Authentication failed";
2660 vnc_write_u32(vs, sizeof(err));
2661 vnc_write(vs, err, sizeof(err));
2663 vnc_client_error(vs);
2666 return 0;
2669 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2671 char local[13];
2673 memcpy(local, version, 12);
2674 local[12] = 0;
2676 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2677 VNC_DEBUG("Malformed protocol version %s\n", local);
2678 vnc_client_error(vs);
2679 return 0;
2681 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2682 if (vs->major != 3 ||
2683 (vs->minor != 3 &&
2684 vs->minor != 4 &&
2685 vs->minor != 5 &&
2686 vs->minor != 7 &&
2687 vs->minor != 8)) {
2688 VNC_DEBUG("Unsupported client version\n");
2689 vnc_write_u32(vs, VNC_AUTH_INVALID);
2690 vnc_flush(vs);
2691 vnc_client_error(vs);
2692 return 0;
2694 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2695 * as equivalent to v3.3 by servers
2697 if (vs->minor == 4 || vs->minor == 5)
2698 vs->minor = 3;
2700 if (vs->minor == 3) {
2701 if (vs->auth == VNC_AUTH_NONE) {
2702 VNC_DEBUG("Tell client auth none\n");
2703 vnc_write_u32(vs, vs->auth);
2704 vnc_flush(vs);
2705 start_client_init(vs);
2706 } else if (vs->auth == VNC_AUTH_VNC) {
2707 VNC_DEBUG("Tell client VNC auth\n");
2708 vnc_write_u32(vs, vs->auth);
2709 vnc_flush(vs);
2710 start_auth_vnc(vs);
2711 } else {
2712 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2713 vnc_write_u32(vs, VNC_AUTH_INVALID);
2714 vnc_flush(vs);
2715 vnc_client_error(vs);
2717 } else {
2718 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2719 vnc_write_u8(vs, 1); /* num auth */
2720 vnc_write_u8(vs, vs->auth);
2721 vnc_read_when(vs, protocol_client_auth, 1);
2722 vnc_flush(vs);
2725 return 0;
2728 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2730 struct VncSurface *vs = &vd->guest;
2732 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2735 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2737 int i, j;
2739 w = (x + w) / VNC_STAT_RECT;
2740 h = (y + h) / VNC_STAT_RECT;
2741 x /= VNC_STAT_RECT;
2742 y /= VNC_STAT_RECT;
2744 for (j = y; j <= h; j++) {
2745 for (i = x; i <= w; i++) {
2746 vs->lossy_rect[j][i] = 1;
2751 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2753 VncState *vs;
2754 int sty = y / VNC_STAT_RECT;
2755 int stx = x / VNC_STAT_RECT;
2756 int has_dirty = 0;
2758 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2759 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2761 QTAILQ_FOREACH(vs, &vd->clients, next) {
2762 int j;
2764 /* kernel send buffers are full -> refresh later */
2765 if (vs->output.offset) {
2766 continue;
2769 if (!vs->lossy_rect[sty][stx]) {
2770 continue;
2773 vs->lossy_rect[sty][stx] = 0;
2774 for (j = 0; j < VNC_STAT_RECT; ++j) {
2775 bitmap_set(vs->dirty[y + j],
2776 x / VNC_DIRTY_PIXELS_PER_BIT,
2777 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2779 has_dirty++;
2782 return has_dirty;
2785 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2787 int width = pixman_image_get_width(vd->guest.fb);
2788 int height = pixman_image_get_height(vd->guest.fb);
2789 int x, y;
2790 struct timeval res;
2791 int has_dirty = 0;
2793 for (y = 0; y < height; y += VNC_STAT_RECT) {
2794 for (x = 0; x < width; x += VNC_STAT_RECT) {
2795 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2797 rect->updated = false;
2801 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2803 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2804 return has_dirty;
2806 vd->guest.last_freq_check = *tv;
2808 for (y = 0; y < height; y += VNC_STAT_RECT) {
2809 for (x = 0; x < width; x += VNC_STAT_RECT) {
2810 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2811 int count = ARRAY_SIZE(rect->times);
2812 struct timeval min, max;
2814 if (!timerisset(&rect->times[count - 1])) {
2815 continue ;
2818 max = rect->times[(rect->idx + count - 1) % count];
2819 qemu_timersub(tv, &max, &res);
2821 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2822 rect->freq = 0;
2823 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2824 memset(rect->times, 0, sizeof (rect->times));
2825 continue ;
2828 min = rect->times[rect->idx];
2829 max = rect->times[(rect->idx + count - 1) % count];
2830 qemu_timersub(&max, &min, &res);
2832 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2833 rect->freq /= count;
2834 rect->freq = 1. / rect->freq;
2837 return has_dirty;
2840 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2842 int i, j;
2843 double total = 0;
2844 int num = 0;
2846 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2847 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2849 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2850 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2851 total += vnc_stat_rect(vs->vd, i, j)->freq;
2852 num++;
2856 if (num) {
2857 return total / num;
2858 } else {
2859 return 0;
2863 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2865 VncRectStat *rect;
2867 rect = vnc_stat_rect(vd, x, y);
2868 if (rect->updated) {
2869 return ;
2871 rect->times[rect->idx] = *tv;
2872 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2873 rect->updated = true;
2876 static int vnc_refresh_server_surface(VncDisplay *vd)
2878 int width = MIN(pixman_image_get_width(vd->guest.fb),
2879 pixman_image_get_width(vd->server));
2880 int height = MIN(pixman_image_get_height(vd->guest.fb),
2881 pixman_image_get_height(vd->server));
2882 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2883 uint8_t *guest_row0 = NULL, *server_row0;
2884 VncState *vs;
2885 int has_dirty = 0;
2886 pixman_image_t *tmpbuf = NULL;
2888 struct timeval tv = { 0, 0 };
2890 if (!vd->non_adaptive) {
2891 gettimeofday(&tv, NULL);
2892 has_dirty = vnc_update_stats(vd, &tv);
2896 * Walk through the guest dirty map.
2897 * Check and copy modified bits from guest to server surface.
2898 * Update server dirty map.
2900 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2901 server_stride = guest_stride = guest_ll =
2902 pixman_image_get_stride(vd->server);
2903 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2904 server_stride);
2905 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2906 int width = pixman_image_get_width(vd->server);
2907 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2908 } else {
2909 int guest_bpp =
2910 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2911 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2912 guest_stride = pixman_image_get_stride(vd->guest.fb);
2913 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2915 line_bytes = MIN(server_stride, guest_ll);
2917 for (;;) {
2918 int x;
2919 uint8_t *guest_ptr, *server_ptr;
2920 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2921 height * VNC_DIRTY_BPL(&vd->guest),
2922 y * VNC_DIRTY_BPL(&vd->guest));
2923 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2924 /* no more dirty bits */
2925 break;
2927 y = offset / VNC_DIRTY_BPL(&vd->guest);
2928 x = offset % VNC_DIRTY_BPL(&vd->guest);
2930 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2932 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2933 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2934 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2935 } else {
2936 guest_ptr = guest_row0 + y * guest_stride;
2938 guest_ptr += x * cmp_bytes;
2940 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2941 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2942 int _cmp_bytes = cmp_bytes;
2943 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2944 continue;
2946 if ((x + 1) * cmp_bytes > line_bytes) {
2947 _cmp_bytes = line_bytes - x * cmp_bytes;
2949 assert(_cmp_bytes >= 0);
2950 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2951 continue;
2953 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2954 if (!vd->non_adaptive) {
2955 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2956 y, &tv);
2958 QTAILQ_FOREACH(vs, &vd->clients, next) {
2959 set_bit(x, vs->dirty[y]);
2961 has_dirty++;
2964 y++;
2966 qemu_pixman_image_unref(tmpbuf);
2967 return has_dirty;
2970 static void vnc_refresh(DisplayChangeListener *dcl)
2972 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2973 VncState *vs, *vn;
2974 int has_dirty, rects = 0;
2976 if (QTAILQ_EMPTY(&vd->clients)) {
2977 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2978 return;
2981 graphic_hw_update(vd->dcl.con);
2983 if (vnc_trylock_display(vd)) {
2984 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2985 return;
2988 has_dirty = vnc_refresh_server_surface(vd);
2989 vnc_unlock_display(vd);
2991 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2992 rects += vnc_update_client(vs, has_dirty, false);
2993 /* vs might be free()ed here */
2996 if (has_dirty && rects) {
2997 vd->dcl.update_interval /= 2;
2998 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2999 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3001 } else {
3002 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3003 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3004 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3009 static void vnc_connect(VncDisplay *vd, int csock,
3010 bool skipauth, bool websocket)
3012 VncState *vs = g_new0(VncState, 1);
3013 int i;
3015 vs->csock = csock;
3016 vs->vd = vd;
3018 buffer_init(&vs->input, "vnc-input/%d", csock);
3019 buffer_init(&vs->output, "vnc-output/%d", csock);
3020 buffer_init(&vs->ws_input, "vnc-ws_input/%d", csock);
3021 buffer_init(&vs->ws_output, "vnc-ws_output/%d", csock);
3022 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%d", csock);
3024 buffer_init(&vs->tight.tight, "vnc-tight/%d", csock);
3025 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%d", csock);
3026 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%d", csock);
3027 #ifdef CONFIG_VNC_JPEG
3028 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%d", csock);
3029 #endif
3030 #ifdef CONFIG_VNC_PNG
3031 buffer_init(&vs->tight.png, "vnc-tight-png/%d", csock);
3032 #endif
3033 buffer_init(&vs->zlib.zlib, "vnc-zlib/%d", csock);
3034 buffer_init(&vs->zrle.zrle, "vnc-zrle/%d", csock);
3035 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%d", csock);
3036 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%d", csock);
3038 if (skipauth) {
3039 vs->auth = VNC_AUTH_NONE;
3040 vs->subauth = VNC_AUTH_INVALID;
3041 } else {
3042 if (websocket) {
3043 vs->auth = vd->ws_auth;
3044 vs->subauth = VNC_AUTH_INVALID;
3045 } else {
3046 vs->auth = vd->auth;
3047 vs->subauth = vd->subauth;
3050 VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
3051 csock, websocket, vs->auth, vs->subauth);
3053 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3054 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3055 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3058 VNC_DEBUG("New client on socket %d\n", csock);
3059 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3060 qemu_set_nonblock(vs->csock);
3061 if (websocket) {
3062 vs->websocket = 1;
3063 if (vd->ws_tls) {
3064 qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io, NULL, vs);
3065 } else {
3066 qemu_set_fd_handler(vs->csock, vncws_handshake_read, NULL, vs);
3068 } else
3070 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
3073 vnc_client_cache_addr(vs);
3074 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3075 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3077 if (!vs->websocket) {
3078 vnc_init_state(vs);
3081 if (vd->num_connecting > vd->connections_limit) {
3082 QTAILQ_FOREACH(vs, &vd->clients, next) {
3083 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3084 vnc_disconnect_start(vs);
3085 return;
3091 void vnc_init_state(VncState *vs)
3093 vs->initialized = true;
3094 VncDisplay *vd = vs->vd;
3095 bool first_client = QTAILQ_EMPTY(&vd->clients);
3097 vs->last_x = -1;
3098 vs->last_y = -1;
3100 vs->as.freq = 44100;
3101 vs->as.nchannels = 2;
3102 vs->as.fmt = AUD_FMT_S16;
3103 vs->as.endianness = 0;
3105 qemu_mutex_init(&vs->output_mutex);
3106 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3108 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3109 if (first_client) {
3110 vnc_update_server_surface(vd);
3113 graphic_hw_update(vd->dcl.con);
3115 vnc_write(vs, "RFB 003.008\n", 12);
3116 vnc_flush(vs);
3117 vnc_read_when(vs, protocol_version, 12);
3118 reset_keys(vs);
3119 if (vs->vd->lock_key_sync)
3120 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3122 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3123 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3125 /* vs might be free()ed here */
3128 static void vnc_listen_read(void *opaque, bool websocket)
3130 VncDisplay *vs = opaque;
3131 struct sockaddr_in addr;
3132 socklen_t addrlen = sizeof(addr);
3133 int csock;
3135 /* Catch-up */
3136 graphic_hw_update(vs->dcl.con);
3137 if (websocket) {
3138 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
3139 } else {
3140 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
3143 if (csock != -1) {
3144 socket_set_nodelay(csock);
3145 vnc_connect(vs, csock, false, websocket);
3149 static void vnc_listen_regular_read(void *opaque)
3151 vnc_listen_read(opaque, false);
3154 static void vnc_listen_websocket_read(void *opaque)
3156 vnc_listen_read(opaque, true);
3159 static const DisplayChangeListenerOps dcl_ops = {
3160 .dpy_name = "vnc",
3161 .dpy_refresh = vnc_refresh,
3162 .dpy_gfx_copy = vnc_dpy_copy,
3163 .dpy_gfx_update = vnc_dpy_update,
3164 .dpy_gfx_switch = vnc_dpy_switch,
3165 .dpy_gfx_check_format = qemu_pixman_check_format,
3166 .dpy_mouse_set = vnc_mouse_set,
3167 .dpy_cursor_define = vnc_dpy_cursor_define,
3170 void vnc_display_init(const char *id)
3172 VncDisplay *vs;
3174 if (vnc_display_find(id) != NULL) {
3175 return;
3177 vs = g_malloc0(sizeof(*vs));
3179 vs->id = strdup(id);
3180 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3182 vs->lsock = -1;
3183 vs->lwebsock = -1;
3185 QTAILQ_INIT(&vs->clients);
3186 vs->expires = TIME_MAX;
3188 if (keyboard_layout) {
3189 trace_vnc_key_map_init(keyboard_layout);
3190 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3191 } else {
3192 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3195 if (!vs->kbd_layout)
3196 exit(1);
3198 qemu_mutex_init(&vs->mutex);
3199 vnc_start_worker_thread();
3201 vs->dcl.ops = &dcl_ops;
3202 register_displaychangelistener(&vs->dcl);
3206 static void vnc_display_close(VncDisplay *vs)
3208 if (!vs)
3209 return;
3210 vs->enabled = false;
3211 vs->is_unix = false;
3212 if (vs->lsock != -1) {
3213 qemu_set_fd_handler(vs->lsock, NULL, NULL, NULL);
3214 close(vs->lsock);
3215 vs->lsock = -1;
3217 vs->ws_enabled = false;
3218 if (vs->lwebsock != -1) {
3219 qemu_set_fd_handler(vs->lwebsock, NULL, NULL, NULL);
3220 close(vs->lwebsock);
3221 vs->lwebsock = -1;
3223 vs->auth = VNC_AUTH_INVALID;
3224 vs->subauth = VNC_AUTH_INVALID;
3225 if (vs->tlscreds) {
3226 object_unparent(OBJECT(vs->tlscreds));
3228 g_free(vs->tlsaclname);
3229 vs->tlsaclname = NULL;
3232 int vnc_display_password(const char *id, const char *password)
3234 VncDisplay *vs = vnc_display_find(id);
3236 if (!vs) {
3237 return -EINVAL;
3239 if (vs->auth == VNC_AUTH_NONE) {
3240 error_printf_unless_qmp("If you want use passwords please enable "
3241 "password auth using '-vnc ${dpy},password'.");
3242 return -EINVAL;
3245 g_free(vs->password);
3246 vs->password = g_strdup(password);
3248 return 0;
3251 int vnc_display_pw_expire(const char *id, time_t expires)
3253 VncDisplay *vs = vnc_display_find(id);
3255 if (!vs) {
3256 return -EINVAL;
3259 vs->expires = expires;
3260 return 0;
3263 char *vnc_display_local_addr(const char *id)
3265 VncDisplay *vs = vnc_display_find(id);
3267 assert(vs);
3268 return vnc_socket_local_addr("%s:%s", vs->lsock);
3271 static QemuOptsList qemu_vnc_opts = {
3272 .name = "vnc",
3273 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3274 .implied_opt_name = "vnc",
3275 .desc = {
3277 .name = "vnc",
3278 .type = QEMU_OPT_STRING,
3280 .name = "websocket",
3281 .type = QEMU_OPT_STRING,
3283 .name = "tls-creds",
3284 .type = QEMU_OPT_STRING,
3286 /* Deprecated in favour of tls-creds */
3287 .name = "x509",
3288 .type = QEMU_OPT_STRING,
3290 .name = "share",
3291 .type = QEMU_OPT_STRING,
3293 .name = "display",
3294 .type = QEMU_OPT_STRING,
3296 .name = "head",
3297 .type = QEMU_OPT_NUMBER,
3299 .name = "connections",
3300 .type = QEMU_OPT_NUMBER,
3302 .name = "to",
3303 .type = QEMU_OPT_NUMBER,
3305 .name = "ipv4",
3306 .type = QEMU_OPT_BOOL,
3308 .name = "ipv6",
3309 .type = QEMU_OPT_BOOL,
3311 .name = "password",
3312 .type = QEMU_OPT_BOOL,
3314 .name = "reverse",
3315 .type = QEMU_OPT_BOOL,
3317 .name = "lock-key-sync",
3318 .type = QEMU_OPT_BOOL,
3320 .name = "sasl",
3321 .type = QEMU_OPT_BOOL,
3323 /* Deprecated in favour of tls-creds */
3324 .name = "tls",
3325 .type = QEMU_OPT_BOOL,
3327 /* Deprecated in favour of tls-creds */
3328 .name = "x509verify",
3329 .type = QEMU_OPT_STRING,
3331 .name = "acl",
3332 .type = QEMU_OPT_BOOL,
3334 .name = "lossy",
3335 .type = QEMU_OPT_BOOL,
3337 .name = "non-adaptive",
3338 .type = QEMU_OPT_BOOL,
3340 { /* end of list */ }
3345 static int
3346 vnc_display_setup_auth(VncDisplay *vs,
3347 bool password,
3348 bool sasl,
3349 bool websocket,
3350 Error **errp)
3353 * We have a choice of 3 authentication options
3355 * 1. none
3356 * 2. vnc
3357 * 3. sasl
3359 * The channel can be run in 2 modes
3361 * 1. clear
3362 * 2. tls
3364 * And TLS can use 2 types of credentials
3366 * 1. anon
3367 * 2. x509
3369 * We thus have 9 possible logical combinations
3371 * 1. clear + none
3372 * 2. clear + vnc
3373 * 3. clear + sasl
3374 * 4. tls + anon + none
3375 * 5. tls + anon + vnc
3376 * 6. tls + anon + sasl
3377 * 7. tls + x509 + none
3378 * 8. tls + x509 + vnc
3379 * 9. tls + x509 + sasl
3381 * These need to be mapped into the VNC auth schemes
3382 * in an appropriate manner. In regular VNC, all the
3383 * TLS options get mapped into VNC_AUTH_VENCRYPT
3384 * sub-auth types.
3386 * In websockets, the https:// protocol already provides
3387 * TLS support, so there is no need to make use of the
3388 * VeNCrypt extension. Furthermore, websockets browser
3389 * clients could not use VeNCrypt even if they wanted to,
3390 * as they cannot control when the TLS handshake takes
3391 * place. Thus there is no option but to rely on https://,
3392 * meaning combinations 4->6 and 7->9 will be mapped to
3393 * VNC auth schemes in the same way as combos 1->3.
3395 * Regardless of fact that we have a different mapping to
3396 * VNC auth mechs for plain VNC vs websockets VNC, the end
3397 * result has the same security characteristics.
3399 if (password) {
3400 if (vs->tlscreds) {
3401 vs->auth = VNC_AUTH_VENCRYPT;
3402 if (websocket) {
3403 vs->ws_tls = true;
3405 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3406 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3407 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3408 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3409 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3410 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3411 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3412 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3413 } else {
3414 error_setg(errp,
3415 "Unsupported TLS cred type %s",
3416 object_get_typename(OBJECT(vs->tlscreds)));
3417 return -1;
3419 } else {
3420 VNC_DEBUG("Initializing VNC server with password auth\n");
3421 vs->auth = VNC_AUTH_VNC;
3422 vs->subauth = VNC_AUTH_INVALID;
3424 if (websocket) {
3425 vs->ws_auth = VNC_AUTH_VNC;
3426 } else {
3427 vs->ws_auth = VNC_AUTH_INVALID;
3429 } else if (sasl) {
3430 if (vs->tlscreds) {
3431 vs->auth = VNC_AUTH_VENCRYPT;
3432 if (websocket) {
3433 vs->ws_tls = true;
3435 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3436 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3437 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3438 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3439 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3440 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3441 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3442 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3443 } else {
3444 error_setg(errp,
3445 "Unsupported TLS cred type %s",
3446 object_get_typename(OBJECT(vs->tlscreds)));
3447 return -1;
3449 } else {
3450 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3451 vs->auth = VNC_AUTH_SASL;
3452 vs->subauth = VNC_AUTH_INVALID;
3454 if (websocket) {
3455 vs->ws_auth = VNC_AUTH_SASL;
3456 } else {
3457 vs->ws_auth = VNC_AUTH_INVALID;
3459 } else {
3460 if (vs->tlscreds) {
3461 vs->auth = VNC_AUTH_VENCRYPT;
3462 if (websocket) {
3463 vs->ws_tls = true;
3465 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3466 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3467 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3468 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3469 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3470 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3471 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3472 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3473 } else {
3474 error_setg(errp,
3475 "Unsupported TLS cred type %s",
3476 object_get_typename(OBJECT(vs->tlscreds)));
3477 return -1;
3479 } else {
3480 VNC_DEBUG("Initializing VNC server with no auth\n");
3481 vs->auth = VNC_AUTH_NONE;
3482 vs->subauth = VNC_AUTH_INVALID;
3484 if (websocket) {
3485 vs->ws_auth = VNC_AUTH_NONE;
3486 } else {
3487 vs->ws_auth = VNC_AUTH_INVALID;
3490 return 0;
3495 * Handle back compat with old CLI syntax by creating some
3496 * suitable QCryptoTLSCreds objects
3498 static QCryptoTLSCreds *
3499 vnc_display_create_creds(bool x509,
3500 bool x509verify,
3501 const char *dir,
3502 const char *id,
3503 Error **errp)
3505 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3506 Object *parent = object_get_objects_root();
3507 Object *creds;
3508 Error *err = NULL;
3510 if (x509) {
3511 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3512 parent,
3513 credsid,
3514 &err,
3515 "endpoint", "server",
3516 "dir", dir,
3517 "verify-peer", x509verify ? "yes" : "no",
3518 NULL);
3519 } else {
3520 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3521 parent,
3522 credsid,
3523 &err,
3524 "endpoint", "server",
3525 NULL);
3528 g_free(credsid);
3530 if (err) {
3531 error_propagate(errp, err);
3532 return NULL;
3535 return QCRYPTO_TLS_CREDS(creds);
3539 void vnc_display_open(const char *id, Error **errp)
3541 VncDisplay *vs = vnc_display_find(id);
3542 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3543 SocketAddress *saddr = NULL, *wsaddr = NULL;
3544 const char *share, *device_id;
3545 QemuConsole *con;
3546 bool password = false;
3547 bool reverse = false;
3548 const char *vnc;
3549 char *h;
3550 const char *credid;
3551 bool sasl = false;
3552 #ifdef CONFIG_VNC_SASL
3553 int saslErr;
3554 #endif
3555 int acl = 0;
3556 int lock_key_sync = 1;
3558 if (!vs) {
3559 error_setg(errp, "VNC display not active");
3560 return;
3562 vnc_display_close(vs);
3564 if (!opts) {
3565 return;
3567 vnc = qemu_opt_get(opts, "vnc");
3568 if (!vnc || strcmp(vnc, "none") == 0) {
3569 return;
3572 h = strrchr(vnc, ':');
3573 if (h) {
3574 size_t hlen = h - vnc;
3576 const char *websocket = qemu_opt_get(opts, "websocket");
3577 int to = qemu_opt_get_number(opts, "to", 0);
3578 bool has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3579 bool has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3581 saddr = g_new0(SocketAddress, 1);
3582 if (websocket) {
3583 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3584 error_setg(errp,
3585 "SHA1 hash support is required for websockets");
3586 goto fail;
3589 wsaddr = g_new0(SocketAddress, 1);
3590 vs->ws_enabled = true;
3593 if (strncmp(vnc, "unix:", 5) == 0) {
3594 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3595 saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
3596 saddr->u.q_unix->path = g_strdup(vnc + 5);
3598 if (vs->ws_enabled) {
3599 error_setg(errp, "UNIX sockets not supported with websock");
3600 goto fail;
3602 } else {
3603 unsigned long long baseport;
3604 saddr->type = SOCKET_ADDRESS_KIND_INET;
3605 saddr->u.inet = g_new0(InetSocketAddress, 1);
3606 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3607 saddr->u.inet->host = g_strndup(vnc + 1, hlen - 2);
3608 } else {
3609 saddr->u.inet->host = g_strndup(vnc, hlen);
3611 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3612 error_setg(errp, "can't convert to a number: %s", h + 1);
3613 goto fail;
3615 if (baseport > 65535 ||
3616 baseport + 5900 > 65535) {
3617 error_setg(errp, "port %s out of range", h + 1);
3618 goto fail;
3620 saddr->u.inet->port = g_strdup_printf(
3621 "%d", (int)baseport + 5900);
3623 if (to) {
3624 saddr->u.inet->has_to = true;
3625 saddr->u.inet->to = to + 5900;
3627 saddr->u.inet->ipv4 = saddr->u.inet->has_ipv4 = has_ipv4;
3628 saddr->u.inet->ipv6 = saddr->u.inet->has_ipv6 = has_ipv6;
3630 if (vs->ws_enabled) {
3631 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3632 wsaddr->u.inet = g_new0(InetSocketAddress, 1);
3633 wsaddr->u.inet->host = g_strdup(saddr->u.inet->host);
3634 wsaddr->u.inet->port = g_strdup(websocket);
3636 if (to) {
3637 wsaddr->u.inet->has_to = true;
3638 wsaddr->u.inet->to = to;
3640 wsaddr->u.inet->ipv4 = wsaddr->u.inet->has_ipv4 = has_ipv4;
3641 wsaddr->u.inet->ipv6 = wsaddr->u.inet->has_ipv6 = has_ipv6;
3644 } else {
3645 error_setg(errp, "no vnc port specified");
3646 goto fail;
3649 password = qemu_opt_get_bool(opts, "password", false);
3650 if (password) {
3651 if (fips_get_state()) {
3652 error_setg(errp,
3653 "VNC password auth disabled due to FIPS mode, "
3654 "consider using the VeNCrypt or SASL authentication "
3655 "methods as an alternative");
3656 goto fail;
3658 if (!qcrypto_cipher_supports(
3659 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3660 error_setg(errp,
3661 "Cipher backend does not support DES RFB algorithm");
3662 goto fail;
3666 reverse = qemu_opt_get_bool(opts, "reverse", false);
3667 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3668 sasl = qemu_opt_get_bool(opts, "sasl", false);
3669 #ifndef CONFIG_VNC_SASL
3670 if (sasl) {
3671 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3672 goto fail;
3674 #endif /* CONFIG_VNC_SASL */
3675 credid = qemu_opt_get(opts, "tls-creds");
3676 if (credid) {
3677 Object *creds;
3678 if (qemu_opt_get(opts, "tls") ||
3679 qemu_opt_get(opts, "x509") ||
3680 qemu_opt_get(opts, "x509verify")) {
3681 error_setg(errp,
3682 "'credid' parameter is mutually exclusive with "
3683 "'tls', 'x509' and 'x509verify' parameters");
3684 goto fail;
3687 creds = object_resolve_path_component(
3688 object_get_objects_root(), credid);
3689 if (!creds) {
3690 error_setg(errp, "No TLS credentials with id '%s'",
3691 credid);
3692 goto fail;
3694 vs->tlscreds = (QCryptoTLSCreds *)
3695 object_dynamic_cast(creds,
3696 TYPE_QCRYPTO_TLS_CREDS);
3697 if (!vs->tlscreds) {
3698 error_setg(errp, "Object with id '%s' is not TLS credentials",
3699 credid);
3700 goto fail;
3702 object_ref(OBJECT(vs->tlscreds));
3704 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3705 error_setg(errp,
3706 "Expecting TLS credentials with a server endpoint");
3707 goto fail;
3709 } else {
3710 const char *path;
3711 bool tls = false, x509 = false, x509verify = false;
3712 tls = qemu_opt_get_bool(opts, "tls", false);
3713 if (tls) {
3714 path = qemu_opt_get(opts, "x509");
3716 if (path) {
3717 x509 = true;
3718 } else {
3719 path = qemu_opt_get(opts, "x509verify");
3720 if (path) {
3721 x509 = true;
3722 x509verify = true;
3725 vs->tlscreds = vnc_display_create_creds(x509,
3726 x509verify,
3727 path,
3728 vs->id,
3729 errp);
3730 if (!vs->tlscreds) {
3731 goto fail;
3735 acl = qemu_opt_get_bool(opts, "acl", false);
3737 share = qemu_opt_get(opts, "share");
3738 if (share) {
3739 if (strcmp(share, "ignore") == 0) {
3740 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3741 } else if (strcmp(share, "allow-exclusive") == 0) {
3742 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3743 } else if (strcmp(share, "force-shared") == 0) {
3744 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3745 } else {
3746 error_setg(errp, "unknown vnc share= option");
3747 goto fail;
3749 } else {
3750 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3752 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3754 #ifdef CONFIG_VNC_JPEG
3755 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3756 #endif
3757 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3758 /* adaptive updates are only used with tight encoding and
3759 * if lossy updates are enabled so we can disable all the
3760 * calculations otherwise */
3761 if (!vs->lossy) {
3762 vs->non_adaptive = true;
3765 if (acl) {
3766 if (strcmp(vs->id, "default") == 0) {
3767 vs->tlsaclname = g_strdup("vnc.x509dname");
3768 } else {
3769 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3771 qemu_acl_init(vs->tlsaclname);
3773 #ifdef CONFIG_VNC_SASL
3774 if (acl && sasl) {
3775 char *aclname;
3777 if (strcmp(vs->id, "default") == 0) {
3778 aclname = g_strdup("vnc.username");
3779 } else {
3780 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3782 vs->sasl.acl = qemu_acl_init(aclname);
3783 g_free(aclname);
3785 #endif
3787 if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
3788 goto fail;
3791 #ifdef CONFIG_VNC_SASL
3792 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3793 error_setg(errp, "Failed to initialize SASL auth: %s",
3794 sasl_errstring(saslErr, NULL, NULL));
3795 goto fail;
3797 #endif
3798 vs->lock_key_sync = lock_key_sync;
3800 device_id = qemu_opt_get(opts, "display");
3801 if (device_id) {
3802 DeviceState *dev;
3803 int head = qemu_opt_get_number(opts, "head", 0);
3805 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3806 if (dev == NULL) {
3807 error_setg(errp, "Device '%s' not found", device_id);
3808 goto fail;
3811 con = qemu_console_lookup_by_device(dev, head);
3812 if (con == NULL) {
3813 error_setg(errp, "Device %s is not bound to a QemuConsole",
3814 device_id);
3815 goto fail;
3817 } else {
3818 con = NULL;
3821 if (con != vs->dcl.con) {
3822 unregister_displaychangelistener(&vs->dcl);
3823 vs->dcl.con = con;
3824 register_displaychangelistener(&vs->dcl);
3827 if (reverse) {
3828 /* connect to viewer */
3829 int csock;
3830 vs->lsock = -1;
3831 vs->lwebsock = -1;
3832 if (vs->ws_enabled) {
3833 error_setg(errp, "Cannot use websockets in reverse mode");
3834 goto fail;
3836 csock = socket_connect(saddr, errp, NULL, NULL);
3837 if (csock < 0) {
3838 goto fail;
3840 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3841 vnc_connect(vs, csock, false, false);
3842 } else {
3843 /* listen for connects */
3844 vs->lsock = socket_listen(saddr, errp);
3845 if (vs->lsock < 0) {
3846 goto fail;
3848 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3849 if (vs->ws_enabled) {
3850 vs->lwebsock = socket_listen(wsaddr, errp);
3851 if (vs->lwebsock < 0) {
3852 if (vs->lsock != -1) {
3853 close(vs->lsock);
3854 vs->lsock = -1;
3856 goto fail;
3859 vs->enabled = true;
3860 qemu_set_fd_handler(vs->lsock, vnc_listen_regular_read, NULL, vs);
3861 if (vs->ws_enabled) {
3862 qemu_set_fd_handler(vs->lwebsock, vnc_listen_websocket_read,
3863 NULL, vs);
3867 qapi_free_SocketAddress(saddr);
3868 qapi_free_SocketAddress(wsaddr);
3869 return;
3871 fail:
3872 qapi_free_SocketAddress(saddr);
3873 qapi_free_SocketAddress(wsaddr);
3874 vs->enabled = false;
3875 vs->ws_enabled = false;
3878 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3880 VncDisplay *vs = vnc_display_find(id);
3882 if (!vs) {
3883 return;
3885 vnc_connect(vs, csock, skipauth, false);
3888 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3890 int i = 2;
3891 char *id;
3893 id = g_strdup("default");
3894 while (qemu_opts_find(olist, id)) {
3895 g_free(id);
3896 id = g_strdup_printf("vnc%d", i++);
3898 qemu_opts_set_id(opts, id);
3901 QemuOpts *vnc_parse(const char *str, Error **errp)
3903 QemuOptsList *olist = qemu_find_opts("vnc");
3904 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3905 const char *id;
3907 if (!opts) {
3908 return NULL;
3911 id = qemu_opts_id(opts);
3912 if (!id) {
3913 /* auto-assign id if not present */
3914 vnc_auto_assign_id(olist, opts);
3916 return opts;
3919 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3921 Error *local_err = NULL;
3922 char *id = (char *)qemu_opts_id(opts);
3924 assert(id);
3925 vnc_display_init(id);
3926 vnc_display_open(id, &local_err);
3927 if (local_err != NULL) {
3928 error_report("Failed to start VNC server: %s",
3929 error_get_pretty(local_err));
3930 error_free(local_err);
3931 exit(1);
3933 return 0;
3936 static void vnc_register_config(void)
3938 qemu_add_opts(&qemu_vnc_opts);
3940 machine_init(vnc_register_config);