vnc: use vnc_{width,height} in vnc_set_area_dirty
[qemu/kevin.git] / ui / vnc.c
blobeb1fcb30a143308b9d06b02fceab3ae1e585e796
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 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
735 vnc_width(vd),
736 vnc_height(vd),
737 NULL, 0);
740 static void vnc_dpy_switch(DisplayChangeListener *dcl,
741 DisplaySurface *surface)
743 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
744 VncState *vs;
745 int width, height;
747 vnc_abort_display_jobs(vd);
748 vd->ds = surface;
750 /* server surface */
751 vnc_update_server_surface(vd);
753 /* guest surface */
754 qemu_pixman_image_unref(vd->guest.fb);
755 vd->guest.fb = pixman_image_ref(surface->image);
756 vd->guest.format = surface->format;
757 width = vnc_width(vd);
758 height = vnc_height(vd);
759 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
760 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
761 width, height);
763 QTAILQ_FOREACH(vs, &vd->clients, next) {
764 vnc_colordepth(vs);
765 vnc_desktop_resize(vs);
766 if (vs->vd->cursor) {
767 vnc_cursor_define(vs);
769 memset(vs->dirty, 0x00, sizeof(vs->dirty));
770 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
771 width, height);
775 /* fastest code */
776 static void vnc_write_pixels_copy(VncState *vs,
777 void *pixels, int size)
779 vnc_write(vs, pixels, size);
782 /* slowest but generic code. */
783 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
785 uint8_t r, g, b;
787 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
788 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
789 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
790 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
791 #else
792 # error need some bits here if you change VNC_SERVER_FB_FORMAT
793 #endif
794 v = (r << vs->client_pf.rshift) |
795 (g << vs->client_pf.gshift) |
796 (b << vs->client_pf.bshift);
797 switch (vs->client_pf.bytes_per_pixel) {
798 case 1:
799 buf[0] = v;
800 break;
801 case 2:
802 if (vs->client_be) {
803 buf[0] = v >> 8;
804 buf[1] = v;
805 } else {
806 buf[1] = v >> 8;
807 buf[0] = v;
809 break;
810 default:
811 case 4:
812 if (vs->client_be) {
813 buf[0] = v >> 24;
814 buf[1] = v >> 16;
815 buf[2] = v >> 8;
816 buf[3] = v;
817 } else {
818 buf[3] = v >> 24;
819 buf[2] = v >> 16;
820 buf[1] = v >> 8;
821 buf[0] = v;
823 break;
827 static void vnc_write_pixels_generic(VncState *vs,
828 void *pixels1, int size)
830 uint8_t buf[4];
832 if (VNC_SERVER_FB_BYTES == 4) {
833 uint32_t *pixels = pixels1;
834 int n, i;
835 n = size >> 2;
836 for (i = 0; i < n; i++) {
837 vnc_convert_pixel(vs, buf, pixels[i]);
838 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
843 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
845 int i;
846 uint8_t *row;
847 VncDisplay *vd = vs->vd;
849 row = vnc_server_fb_ptr(vd, x, y);
850 for (i = 0; i < h; i++) {
851 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
852 row += vnc_server_fb_stride(vd);
854 return 1;
857 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
859 int n = 0;
860 bool encode_raw = false;
861 size_t saved_offs = vs->output.offset;
863 switch(vs->vnc_encoding) {
864 case VNC_ENCODING_ZLIB:
865 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
866 break;
867 case VNC_ENCODING_HEXTILE:
868 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
869 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
870 break;
871 case VNC_ENCODING_TIGHT:
872 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
873 break;
874 case VNC_ENCODING_TIGHT_PNG:
875 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
876 break;
877 case VNC_ENCODING_ZRLE:
878 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
879 break;
880 case VNC_ENCODING_ZYWRLE:
881 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
882 break;
883 default:
884 encode_raw = true;
885 break;
888 /* If the client has the same pixel format as our internal buffer and
889 * a RAW encoding would need less space fall back to RAW encoding to
890 * save bandwidth and processing power in the client. */
891 if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
892 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
893 vs->output.offset = saved_offs;
894 encode_raw = true;
897 if (encode_raw) {
898 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
899 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
902 return n;
905 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
907 /* send bitblit op to the vnc client */
908 vnc_lock_output(vs);
909 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
910 vnc_write_u8(vs, 0);
911 vnc_write_u16(vs, 1); /* number of rects */
912 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
913 vnc_write_u16(vs, src_x);
914 vnc_write_u16(vs, src_y);
915 vnc_unlock_output(vs);
916 vnc_flush(vs);
919 static void vnc_dpy_copy(DisplayChangeListener *dcl,
920 int src_x, int src_y,
921 int dst_x, int dst_y, int w, int h)
923 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
924 VncState *vs, *vn;
925 uint8_t *src_row;
926 uint8_t *dst_row;
927 int i, x, y, pitch, inc, w_lim, s;
928 int cmp_bytes;
930 vnc_refresh_server_surface(vd);
931 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
932 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
933 vs->force_update = 1;
934 vnc_update_client(vs, 1, true);
935 /* vs might be free()ed here */
939 /* do bitblit op on the local surface too */
940 pitch = vnc_server_fb_stride(vd);
941 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
942 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
943 y = dst_y;
944 inc = 1;
945 if (dst_y > src_y) {
946 /* copy backwards */
947 src_row += pitch * (h-1);
948 dst_row += pitch * (h-1);
949 pitch = -pitch;
950 y = dst_y + h - 1;
951 inc = -1;
953 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
954 if (w_lim < 0) {
955 w_lim = w;
956 } else {
957 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
959 for (i = 0; i < h; i++) {
960 for (x = 0; x <= w_lim;
961 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
962 if (x == w_lim) {
963 if ((s = w - w_lim) == 0)
964 break;
965 } else if (!x) {
966 s = (VNC_DIRTY_PIXELS_PER_BIT -
967 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
968 s = MIN(s, w_lim);
969 } else {
970 s = VNC_DIRTY_PIXELS_PER_BIT;
972 cmp_bytes = s * VNC_SERVER_FB_BYTES;
973 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
974 continue;
975 memmove(dst_row, src_row, cmp_bytes);
976 QTAILQ_FOREACH(vs, &vd->clients, next) {
977 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
978 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
979 vs->dirty[y]);
983 src_row += pitch - w * VNC_SERVER_FB_BYTES;
984 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
985 y += inc;
988 QTAILQ_FOREACH(vs, &vd->clients, next) {
989 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
990 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
995 static void vnc_mouse_set(DisplayChangeListener *dcl,
996 int x, int y, int visible)
998 /* can we ask the client(s) to move the pointer ??? */
1001 static int vnc_cursor_define(VncState *vs)
1003 QEMUCursor *c = vs->vd->cursor;
1004 int isize;
1006 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
1007 vnc_lock_output(vs);
1008 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1009 vnc_write_u8(vs, 0); /* padding */
1010 vnc_write_u16(vs, 1); /* # of rects */
1011 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1012 VNC_ENCODING_RICH_CURSOR);
1013 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
1014 vnc_write_pixels_generic(vs, c->data, isize);
1015 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
1016 vnc_unlock_output(vs);
1017 return 0;
1019 return -1;
1022 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1023 QEMUCursor *c)
1025 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1026 VncState *vs;
1028 cursor_put(vd->cursor);
1029 g_free(vd->cursor_mask);
1031 vd->cursor = c;
1032 cursor_get(vd->cursor);
1033 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1034 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1035 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1037 QTAILQ_FOREACH(vs, &vd->clients, next) {
1038 vnc_cursor_define(vs);
1042 static int find_and_clear_dirty_height(VncState *vs,
1043 int y, int last_x, int x, int height)
1045 int h;
1047 for (h = 1; h < (height - y); h++) {
1048 if (!test_bit(last_x, vs->dirty[y + h])) {
1049 break;
1051 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1054 return h;
1057 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1059 vs->has_dirty += has_dirty;
1060 if (vs->need_update && vs->csock != -1) {
1061 VncDisplay *vd = vs->vd;
1062 VncJob *job;
1063 int y;
1064 int height, width;
1065 int n = 0;
1067 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1068 /* kernel send buffers are full -> drop frames to throttle */
1069 return 0;
1071 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1072 return 0;
1075 * Send screen updates to the vnc client using the server
1076 * surface and server dirty map. guest surface updates
1077 * happening in parallel don't disturb us, the next pass will
1078 * send them to the client.
1080 job = vnc_job_new(vs);
1082 height = pixman_image_get_height(vd->server);
1083 width = pixman_image_get_width(vd->server);
1085 y = 0;
1086 for (;;) {
1087 int x, h;
1088 unsigned long x2;
1089 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1090 height * VNC_DIRTY_BPL(vs),
1091 y * VNC_DIRTY_BPL(vs));
1092 if (offset == height * VNC_DIRTY_BPL(vs)) {
1093 /* no more dirty bits */
1094 break;
1096 y = offset / VNC_DIRTY_BPL(vs);
1097 x = offset % VNC_DIRTY_BPL(vs);
1098 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1099 VNC_DIRTY_BPL(vs), x);
1100 bitmap_clear(vs->dirty[y], x, x2 - x);
1101 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1102 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1103 if (x2 > x) {
1104 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1105 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1107 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1108 y += h;
1109 if (y == height) {
1110 break;
1115 vnc_job_push(job);
1116 if (sync) {
1117 vnc_jobs_join(vs);
1119 vs->force_update = 0;
1120 vs->has_dirty = 0;
1121 return n;
1124 if (vs->csock == -1) {
1125 vnc_disconnect_finish(vs);
1126 } else if (sync) {
1127 vnc_jobs_join(vs);
1130 return 0;
1133 /* audio */
1134 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1136 VncState *vs = opaque;
1138 switch (cmd) {
1139 case AUD_CNOTIFY_DISABLE:
1140 vnc_lock_output(vs);
1141 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1142 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1143 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1144 vnc_unlock_output(vs);
1145 vnc_flush(vs);
1146 break;
1148 case AUD_CNOTIFY_ENABLE:
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_BEGIN);
1153 vnc_unlock_output(vs);
1154 vnc_flush(vs);
1155 break;
1159 static void audio_capture_destroy(void *opaque)
1163 static void audio_capture(void *opaque, void *buf, int size)
1165 VncState *vs = opaque;
1167 vnc_lock_output(vs);
1168 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1169 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1170 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1171 vnc_write_u32(vs, size);
1172 vnc_write(vs, buf, size);
1173 vnc_unlock_output(vs);
1174 vnc_flush(vs);
1177 static void audio_add(VncState *vs)
1179 struct audio_capture_ops ops;
1181 if (vs->audio_cap) {
1182 error_report("audio already running");
1183 return;
1186 ops.notify = audio_capture_notify;
1187 ops.destroy = audio_capture_destroy;
1188 ops.capture = audio_capture;
1190 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1191 if (!vs->audio_cap) {
1192 error_report("Failed to add audio capture");
1196 static void audio_del(VncState *vs)
1198 if (vs->audio_cap) {
1199 AUD_del_capture(vs->audio_cap, vs);
1200 vs->audio_cap = NULL;
1204 static void vnc_disconnect_start(VncState *vs)
1206 if (vs->csock == -1)
1207 return;
1208 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1209 qemu_set_fd_handler(vs->csock, NULL, NULL, NULL);
1210 closesocket(vs->csock);
1211 vs->csock = -1;
1214 void vnc_disconnect_finish(VncState *vs)
1216 int i;
1218 vnc_jobs_join(vs); /* Wait encoding jobs */
1220 vnc_lock_output(vs);
1221 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1223 buffer_free(&vs->input);
1224 buffer_free(&vs->output);
1225 buffer_free(&vs->ws_input);
1226 buffer_free(&vs->ws_output);
1228 qapi_free_VncClientInfo(vs->info);
1230 vnc_zlib_clear(vs);
1231 vnc_tight_clear(vs);
1232 vnc_zrle_clear(vs);
1234 qcrypto_tls_session_free(vs->tls);
1235 #ifdef CONFIG_VNC_SASL
1236 vnc_sasl_client_cleanup(vs);
1237 #endif /* CONFIG_VNC_SASL */
1238 audio_del(vs);
1239 vnc_release_modifiers(vs);
1241 if (vs->initialized) {
1242 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1243 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1246 if (vs->vd->lock_key_sync)
1247 qemu_remove_led_event_handler(vs->led);
1248 vnc_unlock_output(vs);
1250 qemu_mutex_destroy(&vs->output_mutex);
1251 if (vs->bh != NULL) {
1252 qemu_bh_delete(vs->bh);
1254 buffer_free(&vs->jobs_buffer);
1256 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1257 g_free(vs->lossy_rect[i]);
1259 g_free(vs->lossy_rect);
1260 g_free(vs);
1263 ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, int last_errno)
1265 if (ret == 0 || ret == -1) {
1266 if (ret == -1) {
1267 switch (last_errno) {
1268 case EINTR:
1269 case EAGAIN:
1270 #ifdef _WIN32
1271 case WSAEWOULDBLOCK:
1272 #endif
1273 return 0;
1274 default:
1275 break;
1279 VNC_DEBUG("Closing down client sock: ret %zd, errno %d\n",
1280 ret, ret < 0 ? last_errno : 0);
1281 vnc_disconnect_start(vs);
1283 return 0;
1285 return ret;
1289 void vnc_client_error(VncState *vs)
1291 VNC_DEBUG("Closing down client sock: protocol error\n");
1292 vnc_disconnect_start(vs);
1296 ssize_t vnc_tls_pull(char *buf, size_t len, void *opaque)
1298 VncState *vs = opaque;
1299 ssize_t ret;
1301 retry:
1302 ret = qemu_recv(vs->csock, buf, len, 0);
1303 if (ret < 0) {
1304 if (errno == EINTR) {
1305 goto retry;
1307 return -1;
1309 return ret;
1313 ssize_t vnc_tls_push(const char *buf, size_t len, void *opaque)
1315 VncState *vs = opaque;
1316 ssize_t ret;
1318 retry:
1319 ret = send(vs->csock, buf, len, 0);
1320 if (ret < 0) {
1321 if (errno == EINTR) {
1322 goto retry;
1324 return -1;
1326 return ret;
1331 * Called to write a chunk of data to the client socket. The data may
1332 * be the raw data, or may have already been encoded by SASL.
1333 * The data will be written either straight onto the socket, or
1334 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1336 * NB, it is theoretically possible to have 2 layers of encryption,
1337 * both SASL, and this TLS layer. It is highly unlikely in practice
1338 * though, since SASL encryption will typically be a no-op if TLS
1339 * is active
1341 * Returns the number of bytes written, which may be less than
1342 * the requested 'datalen' if the socket would block. Returns
1343 * -1 on error, and disconnects the client socket.
1345 ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1347 ssize_t ret;
1348 int err = 0;
1349 if (vs->tls) {
1350 ret = qcrypto_tls_session_write(vs->tls, (const char *)data, datalen);
1351 if (ret < 0) {
1352 err = errno;
1354 } else {
1355 ret = send(vs->csock, (const void *)data, datalen, 0);
1356 if (ret < 0) {
1357 err = socket_error();
1360 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1361 return vnc_client_io_error(vs, ret, err);
1366 * Called to write buffered data to the client socket, when not
1367 * using any SASL SSF encryption layers. Will write as much data
1368 * as possible without blocking. If all buffered data is written,
1369 * will switch the FD poll() handler back to read monitoring.
1371 * Returns the number of bytes written, which may be less than
1372 * the buffered output data if the socket would block. Returns
1373 * -1 on error, and disconnects the client socket.
1375 static ssize_t vnc_client_write_plain(VncState *vs)
1377 ssize_t ret;
1379 #ifdef CONFIG_VNC_SASL
1380 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1381 vs->output.buffer, vs->output.capacity, vs->output.offset,
1382 vs->sasl.waitWriteSSF);
1384 if (vs->sasl.conn &&
1385 vs->sasl.runSSF &&
1386 vs->sasl.waitWriteSSF) {
1387 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1388 if (ret)
1389 vs->sasl.waitWriteSSF -= ret;
1390 } else
1391 #endif /* CONFIG_VNC_SASL */
1392 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1393 if (!ret)
1394 return 0;
1396 buffer_advance(&vs->output, ret);
1398 if (vs->output.offset == 0) {
1399 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
1402 return ret;
1407 * First function called whenever there is data to be written to
1408 * the client socket. Will delegate actual work according to whether
1409 * SASL SSF layers are enabled (thus requiring encryption calls)
1411 static void vnc_client_write_locked(void *opaque)
1413 VncState *vs = opaque;
1415 #ifdef CONFIG_VNC_SASL
1416 if (vs->sasl.conn &&
1417 vs->sasl.runSSF &&
1418 !vs->sasl.waitWriteSSF) {
1419 vnc_client_write_sasl(vs);
1420 } else
1421 #endif /* CONFIG_VNC_SASL */
1423 if (vs->encode_ws) {
1424 vnc_client_write_ws(vs);
1425 } else {
1426 vnc_client_write_plain(vs);
1431 void vnc_client_write(void *opaque)
1433 VncState *vs = opaque;
1435 vnc_lock_output(vs);
1436 if (vs->output.offset || vs->ws_output.offset) {
1437 vnc_client_write_locked(opaque);
1438 } else if (vs->csock != -1) {
1439 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
1441 vnc_unlock_output(vs);
1444 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1446 vs->read_handler = func;
1447 vs->read_handler_expect = expecting;
1452 * Called to read a chunk of data from the client socket. The data may
1453 * be the raw data, or may need to be further decoded by SASL.
1454 * The data will be read either straight from to the socket, or
1455 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1457 * NB, it is theoretically possible to have 2 layers of encryption,
1458 * both SASL, and this TLS layer. It is highly unlikely in practice
1459 * though, since SASL encryption will typically be a no-op if TLS
1460 * is active
1462 * Returns the number of bytes read, which may be less than
1463 * the requested 'datalen' if the socket would block. Returns
1464 * -1 on error, and disconnects the client socket.
1466 ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1468 ssize_t ret;
1469 int err = -1;
1470 if (vs->tls) {
1471 ret = qcrypto_tls_session_read(vs->tls, (char *)data, datalen);
1472 if (ret < 0) {
1473 err = errno;
1475 } else {
1476 ret = qemu_recv(vs->csock, data, datalen, 0);
1477 if (ret < 0) {
1478 err = socket_error();
1481 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1482 return vnc_client_io_error(vs, ret, err);
1487 * Called to read data from the client socket to the input buffer,
1488 * when not using any SASL SSF encryption layers. Will read as much
1489 * data as possible without blocking.
1491 * Returns the number of bytes read. Returns -1 on error, and
1492 * disconnects the client socket.
1494 static ssize_t vnc_client_read_plain(VncState *vs)
1496 ssize_t ret;
1497 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1498 vs->input.buffer, vs->input.capacity, vs->input.offset);
1499 buffer_reserve(&vs->input, 4096);
1500 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1501 if (!ret)
1502 return 0;
1503 vs->input.offset += ret;
1504 return ret;
1507 static void vnc_jobs_bh(void *opaque)
1509 VncState *vs = opaque;
1511 vnc_jobs_consume_buffer(vs);
1515 * First function called whenever there is more data to be read from
1516 * the client socket. Will delegate actual work according to whether
1517 * SASL SSF layers are enabled (thus requiring decryption calls)
1519 void vnc_client_read(void *opaque)
1521 VncState *vs = opaque;
1522 ssize_t ret;
1524 #ifdef CONFIG_VNC_SASL
1525 if (vs->sasl.conn && vs->sasl.runSSF)
1526 ret = vnc_client_read_sasl(vs);
1527 else
1528 #endif /* CONFIG_VNC_SASL */
1529 if (vs->encode_ws) {
1530 ret = vnc_client_read_ws(vs);
1531 if (ret == -1) {
1532 vnc_disconnect_start(vs);
1533 return;
1534 } else if (ret == -2) {
1535 vnc_client_error(vs);
1536 return;
1538 } else {
1539 ret = vnc_client_read_plain(vs);
1541 if (!ret) {
1542 if (vs->csock == -1)
1543 vnc_disconnect_finish(vs);
1544 return;
1547 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1548 size_t len = vs->read_handler_expect;
1549 int ret;
1551 ret = vs->read_handler(vs, vs->input.buffer, len);
1552 if (vs->csock == -1) {
1553 vnc_disconnect_finish(vs);
1554 return;
1557 if (!ret) {
1558 buffer_advance(&vs->input, len);
1559 } else {
1560 vs->read_handler_expect = ret;
1565 void vnc_write(VncState *vs, const void *data, size_t len)
1567 buffer_reserve(&vs->output, len);
1569 if (vs->csock != -1 && buffer_empty(&vs->output)) {
1570 qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs);
1573 buffer_append(&vs->output, data, len);
1576 void vnc_write_s32(VncState *vs, int32_t value)
1578 vnc_write_u32(vs, *(uint32_t *)&value);
1581 void vnc_write_u32(VncState *vs, uint32_t value)
1583 uint8_t buf[4];
1585 buf[0] = (value >> 24) & 0xFF;
1586 buf[1] = (value >> 16) & 0xFF;
1587 buf[2] = (value >> 8) & 0xFF;
1588 buf[3] = value & 0xFF;
1590 vnc_write(vs, buf, 4);
1593 void vnc_write_u16(VncState *vs, uint16_t value)
1595 uint8_t buf[2];
1597 buf[0] = (value >> 8) & 0xFF;
1598 buf[1] = value & 0xFF;
1600 vnc_write(vs, buf, 2);
1603 void vnc_write_u8(VncState *vs, uint8_t value)
1605 vnc_write(vs, (char *)&value, 1);
1608 void vnc_flush(VncState *vs)
1610 vnc_lock_output(vs);
1611 if (vs->csock != -1 && (vs->output.offset ||
1612 vs->ws_output.offset)) {
1613 vnc_client_write_locked(vs);
1615 vnc_unlock_output(vs);
1618 static uint8_t read_u8(uint8_t *data, size_t offset)
1620 return data[offset];
1623 static uint16_t read_u16(uint8_t *data, size_t offset)
1625 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1628 static int32_t read_s32(uint8_t *data, size_t offset)
1630 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1631 (data[offset + 2] << 8) | data[offset + 3]);
1634 uint32_t read_u32(uint8_t *data, size_t offset)
1636 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1637 (data[offset + 2] << 8) | data[offset + 3]);
1640 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1644 static void check_pointer_type_change(Notifier *notifier, void *data)
1646 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1647 int absolute = qemu_input_is_absolute();
1649 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1650 vnc_lock_output(vs);
1651 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1652 vnc_write_u8(vs, 0);
1653 vnc_write_u16(vs, 1);
1654 vnc_framebuffer_update(vs, absolute, 0,
1655 pixman_image_get_width(vs->vd->server),
1656 pixman_image_get_height(vs->vd->server),
1657 VNC_ENCODING_POINTER_TYPE_CHANGE);
1658 vnc_unlock_output(vs);
1659 vnc_flush(vs);
1661 vs->absolute = absolute;
1664 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1666 static uint32_t bmap[INPUT_BUTTON_MAX] = {
1667 [INPUT_BUTTON_LEFT] = 0x01,
1668 [INPUT_BUTTON_MIDDLE] = 0x02,
1669 [INPUT_BUTTON_RIGHT] = 0x04,
1670 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1671 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1673 QemuConsole *con = vs->vd->dcl.con;
1674 int width = pixman_image_get_width(vs->vd->server);
1675 int height = pixman_image_get_height(vs->vd->server);
1677 if (vs->last_bmask != button_mask) {
1678 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1679 vs->last_bmask = button_mask;
1682 if (vs->absolute) {
1683 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1684 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1685 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1686 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1687 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1688 } else {
1689 if (vs->last_x != -1) {
1690 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1691 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1693 vs->last_x = x;
1694 vs->last_y = y;
1696 qemu_input_event_sync();
1699 static void reset_keys(VncState *vs)
1701 int i;
1702 for(i = 0; i < 256; i++) {
1703 if (vs->modifiers_state[i]) {
1704 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1705 vs->modifiers_state[i] = 0;
1710 static void press_key(VncState *vs, int keysym)
1712 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1713 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1714 qemu_input_event_send_key_delay(0);
1715 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1716 qemu_input_event_send_key_delay(0);
1719 static int current_led_state(VncState *vs)
1721 int ledstate = 0;
1723 if (vs->modifiers_state[0x46]) {
1724 ledstate |= QEMU_SCROLL_LOCK_LED;
1726 if (vs->modifiers_state[0x45]) {
1727 ledstate |= QEMU_NUM_LOCK_LED;
1729 if (vs->modifiers_state[0x3a]) {
1730 ledstate |= QEMU_CAPS_LOCK_LED;
1733 return ledstate;
1736 static void vnc_led_state_change(VncState *vs)
1738 int ledstate = 0;
1740 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1741 return;
1744 ledstate = current_led_state(vs);
1745 vnc_lock_output(vs);
1746 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1747 vnc_write_u8(vs, 0);
1748 vnc_write_u16(vs, 1);
1749 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1750 vnc_write_u8(vs, ledstate);
1751 vnc_unlock_output(vs);
1752 vnc_flush(vs);
1755 static void kbd_leds(void *opaque, int ledstate)
1757 VncState *vs = opaque;
1758 int caps, num, scr;
1759 bool has_changed = (ledstate != current_led_state(vs));
1761 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1762 (ledstate & QEMU_NUM_LOCK_LED),
1763 (ledstate & QEMU_SCROLL_LOCK_LED));
1765 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1766 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1767 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1769 if (vs->modifiers_state[0x3a] != caps) {
1770 vs->modifiers_state[0x3a] = caps;
1772 if (vs->modifiers_state[0x45] != num) {
1773 vs->modifiers_state[0x45] = num;
1775 if (vs->modifiers_state[0x46] != scr) {
1776 vs->modifiers_state[0x46] = scr;
1779 /* Sending the current led state message to the client */
1780 if (has_changed) {
1781 vnc_led_state_change(vs);
1785 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1787 /* QEMU console switch */
1788 switch(keycode) {
1789 case 0x2a: /* Left Shift */
1790 case 0x36: /* Right Shift */
1791 case 0x1d: /* Left CTRL */
1792 case 0x9d: /* Right CTRL */
1793 case 0x38: /* Left ALT */
1794 case 0xb8: /* Right ALT */
1795 if (down)
1796 vs->modifiers_state[keycode] = 1;
1797 else
1798 vs->modifiers_state[keycode] = 0;
1799 break;
1800 case 0x02 ... 0x0a: /* '1' to '9' keys */
1801 if (vs->vd->dcl.con == NULL &&
1802 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1803 /* Reset the modifiers sent to the current console */
1804 reset_keys(vs);
1805 console_select(keycode - 0x02);
1806 return;
1808 break;
1809 case 0x3a: /* CapsLock */
1810 case 0x45: /* NumLock */
1811 if (down)
1812 vs->modifiers_state[keycode] ^= 1;
1813 break;
1816 /* Turn off the lock state sync logic if the client support the led
1817 state extension.
1819 if (down && vs->vd->lock_key_sync &&
1820 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1821 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1822 /* If the numlock state needs to change then simulate an additional
1823 keypress before sending this one. This will happen if the user
1824 toggles numlock away from the VNC window.
1826 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1827 if (!vs->modifiers_state[0x45]) {
1828 trace_vnc_key_sync_numlock(true);
1829 vs->modifiers_state[0x45] = 1;
1830 press_key(vs, 0xff7f);
1832 } else {
1833 if (vs->modifiers_state[0x45]) {
1834 trace_vnc_key_sync_numlock(false);
1835 vs->modifiers_state[0x45] = 0;
1836 press_key(vs, 0xff7f);
1841 if (down && vs->vd->lock_key_sync &&
1842 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1843 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1844 /* If the capslock state needs to change then simulate an additional
1845 keypress before sending this one. This will happen if the user
1846 toggles capslock away from the VNC window.
1848 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1849 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1850 int capslock = !!(vs->modifiers_state[0x3a]);
1851 if (capslock) {
1852 if (uppercase == shift) {
1853 trace_vnc_key_sync_capslock(false);
1854 vs->modifiers_state[0x3a] = 0;
1855 press_key(vs, 0xffe5);
1857 } else {
1858 if (uppercase != shift) {
1859 trace_vnc_key_sync_capslock(true);
1860 vs->modifiers_state[0x3a] = 1;
1861 press_key(vs, 0xffe5);
1866 if (qemu_console_is_graphic(NULL)) {
1867 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1868 } else {
1869 bool numlock = vs->modifiers_state[0x45];
1870 bool control = (vs->modifiers_state[0x1d] ||
1871 vs->modifiers_state[0x9d]);
1872 /* QEMU console emulation */
1873 if (down) {
1874 switch (keycode) {
1875 case 0x2a: /* Left Shift */
1876 case 0x36: /* Right Shift */
1877 case 0x1d: /* Left CTRL */
1878 case 0x9d: /* Right CTRL */
1879 case 0x38: /* Left ALT */
1880 case 0xb8: /* Right ALT */
1881 break;
1882 case 0xc8:
1883 kbd_put_keysym(QEMU_KEY_UP);
1884 break;
1885 case 0xd0:
1886 kbd_put_keysym(QEMU_KEY_DOWN);
1887 break;
1888 case 0xcb:
1889 kbd_put_keysym(QEMU_KEY_LEFT);
1890 break;
1891 case 0xcd:
1892 kbd_put_keysym(QEMU_KEY_RIGHT);
1893 break;
1894 case 0xd3:
1895 kbd_put_keysym(QEMU_KEY_DELETE);
1896 break;
1897 case 0xc7:
1898 kbd_put_keysym(QEMU_KEY_HOME);
1899 break;
1900 case 0xcf:
1901 kbd_put_keysym(QEMU_KEY_END);
1902 break;
1903 case 0xc9:
1904 kbd_put_keysym(QEMU_KEY_PAGEUP);
1905 break;
1906 case 0xd1:
1907 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1908 break;
1910 case 0x47:
1911 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1912 break;
1913 case 0x48:
1914 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1915 break;
1916 case 0x49:
1917 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1918 break;
1919 case 0x4b:
1920 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1921 break;
1922 case 0x4c:
1923 kbd_put_keysym('5');
1924 break;
1925 case 0x4d:
1926 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1927 break;
1928 case 0x4f:
1929 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1930 break;
1931 case 0x50:
1932 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1933 break;
1934 case 0x51:
1935 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1936 break;
1937 case 0x52:
1938 kbd_put_keysym('0');
1939 break;
1940 case 0x53:
1941 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1942 break;
1944 case 0xb5:
1945 kbd_put_keysym('/');
1946 break;
1947 case 0x37:
1948 kbd_put_keysym('*');
1949 break;
1950 case 0x4a:
1951 kbd_put_keysym('-');
1952 break;
1953 case 0x4e:
1954 kbd_put_keysym('+');
1955 break;
1956 case 0x9c:
1957 kbd_put_keysym('\n');
1958 break;
1960 default:
1961 if (control) {
1962 kbd_put_keysym(sym & 0x1f);
1963 } else {
1964 kbd_put_keysym(sym);
1966 break;
1972 static void vnc_release_modifiers(VncState *vs)
1974 static const int keycodes[] = {
1975 /* shift, control, alt keys, both left & right */
1976 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1978 int i, keycode;
1980 if (!qemu_console_is_graphic(NULL)) {
1981 return;
1983 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1984 keycode = keycodes[i];
1985 if (!vs->modifiers_state[keycode]) {
1986 continue;
1988 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1992 static const char *code2name(int keycode)
1994 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1997 static void key_event(VncState *vs, int down, uint32_t sym)
1999 int keycode;
2000 int lsym = sym;
2002 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2003 lsym = lsym - 'A' + 'a';
2006 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
2007 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2008 do_key_event(vs, down, keycode, sym);
2011 static void ext_key_event(VncState *vs, int down,
2012 uint32_t sym, uint16_t keycode)
2014 /* if the user specifies a keyboard layout, always use it */
2015 if (keyboard_layout) {
2016 key_event(vs, down, sym);
2017 } else {
2018 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2019 do_key_event(vs, down, keycode, sym);
2023 static void framebuffer_update_request(VncState *vs, int incremental,
2024 int x, int y, int w, int h)
2026 vs->need_update = 1;
2028 if (incremental) {
2029 return;
2032 vs->force_update = 1;
2033 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
2036 static void send_ext_key_event_ack(VncState *vs)
2038 vnc_lock_output(vs);
2039 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2040 vnc_write_u8(vs, 0);
2041 vnc_write_u16(vs, 1);
2042 vnc_framebuffer_update(vs, 0, 0,
2043 pixman_image_get_width(vs->vd->server),
2044 pixman_image_get_height(vs->vd->server),
2045 VNC_ENCODING_EXT_KEY_EVENT);
2046 vnc_unlock_output(vs);
2047 vnc_flush(vs);
2050 static void send_ext_audio_ack(VncState *vs)
2052 vnc_lock_output(vs);
2053 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2054 vnc_write_u8(vs, 0);
2055 vnc_write_u16(vs, 1);
2056 vnc_framebuffer_update(vs, 0, 0,
2057 pixman_image_get_width(vs->vd->server),
2058 pixman_image_get_height(vs->vd->server),
2059 VNC_ENCODING_AUDIO);
2060 vnc_unlock_output(vs);
2061 vnc_flush(vs);
2064 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2066 int i;
2067 unsigned int enc = 0;
2069 vs->features = 0;
2070 vs->vnc_encoding = 0;
2071 vs->tight.compression = 9;
2072 vs->tight.quality = -1; /* Lossless by default */
2073 vs->absolute = -1;
2076 * Start from the end because the encodings are sent in order of preference.
2077 * This way the preferred encoding (first encoding defined in the array)
2078 * will be set at the end of the loop.
2080 for (i = n_encodings - 1; i >= 0; i--) {
2081 enc = encodings[i];
2082 switch (enc) {
2083 case VNC_ENCODING_RAW:
2084 vs->vnc_encoding = enc;
2085 break;
2086 case VNC_ENCODING_COPYRECT:
2087 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2088 break;
2089 case VNC_ENCODING_HEXTILE:
2090 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2091 vs->vnc_encoding = enc;
2092 break;
2093 case VNC_ENCODING_TIGHT:
2094 vs->features |= VNC_FEATURE_TIGHT_MASK;
2095 vs->vnc_encoding = enc;
2096 break;
2097 #ifdef CONFIG_VNC_PNG
2098 case VNC_ENCODING_TIGHT_PNG:
2099 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2100 vs->vnc_encoding = enc;
2101 break;
2102 #endif
2103 case VNC_ENCODING_ZLIB:
2104 vs->features |= VNC_FEATURE_ZLIB_MASK;
2105 vs->vnc_encoding = enc;
2106 break;
2107 case VNC_ENCODING_ZRLE:
2108 vs->features |= VNC_FEATURE_ZRLE_MASK;
2109 vs->vnc_encoding = enc;
2110 break;
2111 case VNC_ENCODING_ZYWRLE:
2112 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2113 vs->vnc_encoding = enc;
2114 break;
2115 case VNC_ENCODING_DESKTOPRESIZE:
2116 vs->features |= VNC_FEATURE_RESIZE_MASK;
2117 break;
2118 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2119 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2120 break;
2121 case VNC_ENCODING_RICH_CURSOR:
2122 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2123 break;
2124 case VNC_ENCODING_EXT_KEY_EVENT:
2125 send_ext_key_event_ack(vs);
2126 break;
2127 case VNC_ENCODING_AUDIO:
2128 send_ext_audio_ack(vs);
2129 break;
2130 case VNC_ENCODING_WMVi:
2131 vs->features |= VNC_FEATURE_WMVI_MASK;
2132 break;
2133 case VNC_ENCODING_LED_STATE:
2134 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2135 break;
2136 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2137 vs->tight.compression = (enc & 0x0F);
2138 break;
2139 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2140 if (vs->vd->lossy) {
2141 vs->tight.quality = (enc & 0x0F);
2143 break;
2144 default:
2145 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2146 break;
2149 vnc_desktop_resize(vs);
2150 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2151 vnc_led_state_change(vs);
2154 static void set_pixel_conversion(VncState *vs)
2156 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2158 if (fmt == VNC_SERVER_FB_FORMAT) {
2159 vs->write_pixels = vnc_write_pixels_copy;
2160 vnc_hextile_set_pixel_conversion(vs, 0);
2161 } else {
2162 vs->write_pixels = vnc_write_pixels_generic;
2163 vnc_hextile_set_pixel_conversion(vs, 1);
2167 static void set_pixel_format(VncState *vs,
2168 int bits_per_pixel, int depth,
2169 int big_endian_flag, int true_color_flag,
2170 int red_max, int green_max, int blue_max,
2171 int red_shift, int green_shift, int blue_shift)
2173 if (!true_color_flag) {
2174 vnc_client_error(vs);
2175 return;
2178 switch (bits_per_pixel) {
2179 case 8:
2180 case 16:
2181 case 32:
2182 break;
2183 default:
2184 vnc_client_error(vs);
2185 return;
2188 vs->client_pf.rmax = red_max;
2189 vs->client_pf.rbits = hweight_long(red_max);
2190 vs->client_pf.rshift = red_shift;
2191 vs->client_pf.rmask = red_max << red_shift;
2192 vs->client_pf.gmax = green_max;
2193 vs->client_pf.gbits = hweight_long(green_max);
2194 vs->client_pf.gshift = green_shift;
2195 vs->client_pf.gmask = green_max << green_shift;
2196 vs->client_pf.bmax = blue_max;
2197 vs->client_pf.bbits = hweight_long(blue_max);
2198 vs->client_pf.bshift = blue_shift;
2199 vs->client_pf.bmask = blue_max << blue_shift;
2200 vs->client_pf.bits_per_pixel = bits_per_pixel;
2201 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2202 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2203 vs->client_be = big_endian_flag;
2205 set_pixel_conversion(vs);
2207 graphic_hw_invalidate(vs->vd->dcl.con);
2208 graphic_hw_update(vs->vd->dcl.con);
2211 static void pixel_format_message (VncState *vs) {
2212 char pad[3] = { 0, 0, 0 };
2214 vs->client_pf = qemu_default_pixelformat(32);
2216 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2217 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2219 #ifdef HOST_WORDS_BIGENDIAN
2220 vnc_write_u8(vs, 1); /* big-endian-flag */
2221 #else
2222 vnc_write_u8(vs, 0); /* big-endian-flag */
2223 #endif
2224 vnc_write_u8(vs, 1); /* true-color-flag */
2225 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2226 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2227 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2228 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2229 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2230 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2231 vnc_write(vs, pad, 3); /* padding */
2233 vnc_hextile_set_pixel_conversion(vs, 0);
2234 vs->write_pixels = vnc_write_pixels_copy;
2237 static void vnc_colordepth(VncState *vs)
2239 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2240 /* Sending a WMVi message to notify the client*/
2241 vnc_lock_output(vs);
2242 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2243 vnc_write_u8(vs, 0);
2244 vnc_write_u16(vs, 1); /* number of rects */
2245 vnc_framebuffer_update(vs, 0, 0,
2246 pixman_image_get_width(vs->vd->server),
2247 pixman_image_get_height(vs->vd->server),
2248 VNC_ENCODING_WMVi);
2249 pixel_format_message(vs);
2250 vnc_unlock_output(vs);
2251 vnc_flush(vs);
2252 } else {
2253 set_pixel_conversion(vs);
2257 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2259 int i;
2260 uint16_t limit;
2261 VncDisplay *vd = vs->vd;
2263 if (data[0] > 3) {
2264 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2267 switch (data[0]) {
2268 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2269 if (len == 1)
2270 return 20;
2272 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2273 read_u8(data, 6), read_u8(data, 7),
2274 read_u16(data, 8), read_u16(data, 10),
2275 read_u16(data, 12), read_u8(data, 14),
2276 read_u8(data, 15), read_u8(data, 16));
2277 break;
2278 case VNC_MSG_CLIENT_SET_ENCODINGS:
2279 if (len == 1)
2280 return 4;
2282 if (len == 4) {
2283 limit = read_u16(data, 2);
2284 if (limit > 0)
2285 return 4 + (limit * 4);
2286 } else
2287 limit = read_u16(data, 2);
2289 for (i = 0; i < limit; i++) {
2290 int32_t val = read_s32(data, 4 + (i * 4));
2291 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2294 set_encodings(vs, (int32_t *)(data + 4), limit);
2295 break;
2296 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2297 if (len == 1)
2298 return 10;
2300 framebuffer_update_request(vs,
2301 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2302 read_u16(data, 6), read_u16(data, 8));
2303 break;
2304 case VNC_MSG_CLIENT_KEY_EVENT:
2305 if (len == 1)
2306 return 8;
2308 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2309 break;
2310 case VNC_MSG_CLIENT_POINTER_EVENT:
2311 if (len == 1)
2312 return 6;
2314 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2315 break;
2316 case VNC_MSG_CLIENT_CUT_TEXT:
2317 if (len == 1) {
2318 return 8;
2320 if (len == 8) {
2321 uint32_t dlen = read_u32(data, 4);
2322 if (dlen > (1 << 20)) {
2323 error_report("vnc: client_cut_text msg payload has %u bytes"
2324 " which exceeds our limit of 1MB.", dlen);
2325 vnc_client_error(vs);
2326 break;
2328 if (dlen > 0) {
2329 return 8 + dlen;
2333 client_cut_text(vs, read_u32(data, 4), data + 8);
2334 break;
2335 case VNC_MSG_CLIENT_QEMU:
2336 if (len == 1)
2337 return 2;
2339 switch (read_u8(data, 1)) {
2340 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2341 if (len == 2)
2342 return 12;
2344 ext_key_event(vs, read_u16(data, 2),
2345 read_u32(data, 4), read_u32(data, 8));
2346 break;
2347 case VNC_MSG_CLIENT_QEMU_AUDIO:
2348 if (len == 2)
2349 return 4;
2351 switch (read_u16 (data, 2)) {
2352 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2353 audio_add(vs);
2354 break;
2355 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2356 audio_del(vs);
2357 break;
2358 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2359 if (len == 4)
2360 return 10;
2361 switch (read_u8(data, 4)) {
2362 case 0: vs->as.fmt = AUD_FMT_U8; break;
2363 case 1: vs->as.fmt = AUD_FMT_S8; break;
2364 case 2: vs->as.fmt = AUD_FMT_U16; break;
2365 case 3: vs->as.fmt = AUD_FMT_S16; break;
2366 case 4: vs->as.fmt = AUD_FMT_U32; break;
2367 case 5: vs->as.fmt = AUD_FMT_S32; break;
2368 default:
2369 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2370 vnc_client_error(vs);
2371 break;
2373 vs->as.nchannels = read_u8(data, 5);
2374 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2375 VNC_DEBUG("Invalid audio channel coount %d\n",
2376 read_u8(data, 5));
2377 vnc_client_error(vs);
2378 break;
2380 vs->as.freq = read_u32(data, 6);
2381 break;
2382 default:
2383 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2384 vnc_client_error(vs);
2385 break;
2387 break;
2389 default:
2390 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2391 vnc_client_error(vs);
2392 break;
2394 break;
2395 default:
2396 VNC_DEBUG("Msg: %d\n", data[0]);
2397 vnc_client_error(vs);
2398 break;
2401 vnc_read_when(vs, protocol_client_msg, 1);
2402 return 0;
2405 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2407 char buf[1024];
2408 VncShareMode mode;
2409 int size;
2411 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2412 switch (vs->vd->share_policy) {
2413 case VNC_SHARE_POLICY_IGNORE:
2415 * Ignore the shared flag. Nothing to do here.
2417 * Doesn't conform to the rfb spec but is traditional qemu
2418 * behavior, thus left here as option for compatibility
2419 * reasons.
2421 break;
2422 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2424 * Policy: Allow clients ask for exclusive access.
2426 * Implementation: When a client asks for exclusive access,
2427 * disconnect all others. Shared connects are allowed as long
2428 * as no exclusive connection exists.
2430 * This is how the rfb spec suggests to handle the shared flag.
2432 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2433 VncState *client;
2434 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2435 if (vs == client) {
2436 continue;
2438 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2439 client->share_mode != VNC_SHARE_MODE_SHARED) {
2440 continue;
2442 vnc_disconnect_start(client);
2445 if (mode == VNC_SHARE_MODE_SHARED) {
2446 if (vs->vd->num_exclusive > 0) {
2447 vnc_disconnect_start(vs);
2448 return 0;
2451 break;
2452 case VNC_SHARE_POLICY_FORCE_SHARED:
2454 * Policy: Shared connects only.
2455 * Implementation: Disallow clients asking for exclusive access.
2457 * Useful for shared desktop sessions where you don't want
2458 * someone forgetting to say -shared when running the vnc
2459 * client disconnect everybody else.
2461 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2462 vnc_disconnect_start(vs);
2463 return 0;
2465 break;
2467 vnc_set_share_mode(vs, mode);
2469 if (vs->vd->num_shared > vs->vd->connections_limit) {
2470 vnc_disconnect_start(vs);
2471 return 0;
2474 vs->client_width = pixman_image_get_width(vs->vd->server);
2475 vs->client_height = pixman_image_get_height(vs->vd->server);
2476 vnc_write_u16(vs, vs->client_width);
2477 vnc_write_u16(vs, vs->client_height);
2479 pixel_format_message(vs);
2481 if (qemu_name)
2482 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2483 else
2484 size = snprintf(buf, sizeof(buf), "QEMU");
2486 vnc_write_u32(vs, size);
2487 vnc_write(vs, buf, size);
2488 vnc_flush(vs);
2490 vnc_client_cache_auth(vs);
2491 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2493 vnc_read_when(vs, protocol_client_msg, 1);
2495 return 0;
2498 void start_client_init(VncState *vs)
2500 vnc_read_when(vs, protocol_client_init, 1);
2503 static void make_challenge(VncState *vs)
2505 int i;
2507 srand(time(NULL)+getpid()+getpid()*987654+rand());
2509 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2510 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2513 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2515 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2516 size_t i, pwlen;
2517 unsigned char key[8];
2518 time_t now = time(NULL);
2519 QCryptoCipher *cipher = NULL;
2520 Error *err = NULL;
2522 if (!vs->vd->password) {
2523 VNC_DEBUG("No password configured on server");
2524 goto reject;
2526 if (vs->vd->expires < now) {
2527 VNC_DEBUG("Password is expired");
2528 goto reject;
2531 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2533 /* Calculate the expected challenge response */
2534 pwlen = strlen(vs->vd->password);
2535 for (i=0; i<sizeof(key); i++)
2536 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2538 cipher = qcrypto_cipher_new(
2539 QCRYPTO_CIPHER_ALG_DES_RFB,
2540 QCRYPTO_CIPHER_MODE_ECB,
2541 key, G_N_ELEMENTS(key),
2542 &err);
2543 if (!cipher) {
2544 VNC_DEBUG("Cannot initialize cipher %s",
2545 error_get_pretty(err));
2546 error_free(err);
2547 goto reject;
2550 if (qcrypto_cipher_encrypt(cipher,
2551 vs->challenge,
2552 response,
2553 VNC_AUTH_CHALLENGE_SIZE,
2554 &err) < 0) {
2555 VNC_DEBUG("Cannot encrypt challenge %s",
2556 error_get_pretty(err));
2557 error_free(err);
2558 goto reject;
2561 /* Compare expected vs actual challenge response */
2562 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2563 VNC_DEBUG("Client challenge response did not match\n");
2564 goto reject;
2565 } else {
2566 VNC_DEBUG("Accepting VNC challenge response\n");
2567 vnc_write_u32(vs, 0); /* Accept auth */
2568 vnc_flush(vs);
2570 start_client_init(vs);
2573 qcrypto_cipher_free(cipher);
2574 return 0;
2576 reject:
2577 vnc_write_u32(vs, 1); /* Reject auth */
2578 if (vs->minor >= 8) {
2579 static const char err[] = "Authentication failed";
2580 vnc_write_u32(vs, sizeof(err));
2581 vnc_write(vs, err, sizeof(err));
2583 vnc_flush(vs);
2584 vnc_client_error(vs);
2585 qcrypto_cipher_free(cipher);
2586 return 0;
2589 void start_auth_vnc(VncState *vs)
2591 make_challenge(vs);
2592 /* Send client a 'random' challenge */
2593 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2594 vnc_flush(vs);
2596 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2600 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2602 /* We only advertise 1 auth scheme at a time, so client
2603 * must pick the one we sent. Verify this */
2604 if (data[0] != vs->auth) { /* Reject auth */
2605 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2606 vnc_write_u32(vs, 1);
2607 if (vs->minor >= 8) {
2608 static const char err[] = "Authentication failed";
2609 vnc_write_u32(vs, sizeof(err));
2610 vnc_write(vs, err, sizeof(err));
2612 vnc_client_error(vs);
2613 } else { /* Accept requested auth */
2614 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2615 switch (vs->auth) {
2616 case VNC_AUTH_NONE:
2617 VNC_DEBUG("Accept auth none\n");
2618 if (vs->minor >= 8) {
2619 vnc_write_u32(vs, 0); /* Accept auth completion */
2620 vnc_flush(vs);
2622 start_client_init(vs);
2623 break;
2625 case VNC_AUTH_VNC:
2626 VNC_DEBUG("Start VNC auth\n");
2627 start_auth_vnc(vs);
2628 break;
2630 case VNC_AUTH_VENCRYPT:
2631 VNC_DEBUG("Accept VeNCrypt auth\n");
2632 start_auth_vencrypt(vs);
2633 break;
2635 #ifdef CONFIG_VNC_SASL
2636 case VNC_AUTH_SASL:
2637 VNC_DEBUG("Accept SASL auth\n");
2638 start_auth_sasl(vs);
2639 break;
2640 #endif /* CONFIG_VNC_SASL */
2642 default: /* Should not be possible, but just in case */
2643 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2644 vnc_write_u8(vs, 1);
2645 if (vs->minor >= 8) {
2646 static const char err[] = "Authentication failed";
2647 vnc_write_u32(vs, sizeof(err));
2648 vnc_write(vs, err, sizeof(err));
2650 vnc_client_error(vs);
2653 return 0;
2656 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2658 char local[13];
2660 memcpy(local, version, 12);
2661 local[12] = 0;
2663 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2664 VNC_DEBUG("Malformed protocol version %s\n", local);
2665 vnc_client_error(vs);
2666 return 0;
2668 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2669 if (vs->major != 3 ||
2670 (vs->minor != 3 &&
2671 vs->minor != 4 &&
2672 vs->minor != 5 &&
2673 vs->minor != 7 &&
2674 vs->minor != 8)) {
2675 VNC_DEBUG("Unsupported client version\n");
2676 vnc_write_u32(vs, VNC_AUTH_INVALID);
2677 vnc_flush(vs);
2678 vnc_client_error(vs);
2679 return 0;
2681 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2682 * as equivalent to v3.3 by servers
2684 if (vs->minor == 4 || vs->minor == 5)
2685 vs->minor = 3;
2687 if (vs->minor == 3) {
2688 if (vs->auth == VNC_AUTH_NONE) {
2689 VNC_DEBUG("Tell client auth none\n");
2690 vnc_write_u32(vs, vs->auth);
2691 vnc_flush(vs);
2692 start_client_init(vs);
2693 } else if (vs->auth == VNC_AUTH_VNC) {
2694 VNC_DEBUG("Tell client VNC auth\n");
2695 vnc_write_u32(vs, vs->auth);
2696 vnc_flush(vs);
2697 start_auth_vnc(vs);
2698 } else {
2699 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2700 vnc_write_u32(vs, VNC_AUTH_INVALID);
2701 vnc_flush(vs);
2702 vnc_client_error(vs);
2704 } else {
2705 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2706 vnc_write_u8(vs, 1); /* num auth */
2707 vnc_write_u8(vs, vs->auth);
2708 vnc_read_when(vs, protocol_client_auth, 1);
2709 vnc_flush(vs);
2712 return 0;
2715 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2717 struct VncSurface *vs = &vd->guest;
2719 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2722 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2724 int i, j;
2726 w = (x + w) / VNC_STAT_RECT;
2727 h = (y + h) / VNC_STAT_RECT;
2728 x /= VNC_STAT_RECT;
2729 y /= VNC_STAT_RECT;
2731 for (j = y; j <= h; j++) {
2732 for (i = x; i <= w; i++) {
2733 vs->lossy_rect[j][i] = 1;
2738 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2740 VncState *vs;
2741 int sty = y / VNC_STAT_RECT;
2742 int stx = x / VNC_STAT_RECT;
2743 int has_dirty = 0;
2745 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2746 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2748 QTAILQ_FOREACH(vs, &vd->clients, next) {
2749 int j;
2751 /* kernel send buffers are full -> refresh later */
2752 if (vs->output.offset) {
2753 continue;
2756 if (!vs->lossy_rect[sty][stx]) {
2757 continue;
2760 vs->lossy_rect[sty][stx] = 0;
2761 for (j = 0; j < VNC_STAT_RECT; ++j) {
2762 bitmap_set(vs->dirty[y + j],
2763 x / VNC_DIRTY_PIXELS_PER_BIT,
2764 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2766 has_dirty++;
2769 return has_dirty;
2772 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2774 int width = pixman_image_get_width(vd->guest.fb);
2775 int height = pixman_image_get_height(vd->guest.fb);
2776 int x, y;
2777 struct timeval res;
2778 int has_dirty = 0;
2780 for (y = 0; y < height; y += VNC_STAT_RECT) {
2781 for (x = 0; x < width; x += VNC_STAT_RECT) {
2782 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2784 rect->updated = false;
2788 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2790 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2791 return has_dirty;
2793 vd->guest.last_freq_check = *tv;
2795 for (y = 0; y < height; y += VNC_STAT_RECT) {
2796 for (x = 0; x < width; x += VNC_STAT_RECT) {
2797 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2798 int count = ARRAY_SIZE(rect->times);
2799 struct timeval min, max;
2801 if (!timerisset(&rect->times[count - 1])) {
2802 continue ;
2805 max = rect->times[(rect->idx + count - 1) % count];
2806 qemu_timersub(tv, &max, &res);
2808 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2809 rect->freq = 0;
2810 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2811 memset(rect->times, 0, sizeof (rect->times));
2812 continue ;
2815 min = rect->times[rect->idx];
2816 max = rect->times[(rect->idx + count - 1) % count];
2817 qemu_timersub(&max, &min, &res);
2819 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2820 rect->freq /= count;
2821 rect->freq = 1. / rect->freq;
2824 return has_dirty;
2827 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2829 int i, j;
2830 double total = 0;
2831 int num = 0;
2833 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2834 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2836 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2837 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2838 total += vnc_stat_rect(vs->vd, i, j)->freq;
2839 num++;
2843 if (num) {
2844 return total / num;
2845 } else {
2846 return 0;
2850 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2852 VncRectStat *rect;
2854 rect = vnc_stat_rect(vd, x, y);
2855 if (rect->updated) {
2856 return ;
2858 rect->times[rect->idx] = *tv;
2859 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2860 rect->updated = true;
2863 static int vnc_refresh_server_surface(VncDisplay *vd)
2865 int width = MIN(pixman_image_get_width(vd->guest.fb),
2866 pixman_image_get_width(vd->server));
2867 int height = MIN(pixman_image_get_height(vd->guest.fb),
2868 pixman_image_get_height(vd->server));
2869 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2870 uint8_t *guest_row0 = NULL, *server_row0;
2871 VncState *vs;
2872 int has_dirty = 0;
2873 pixman_image_t *tmpbuf = NULL;
2875 struct timeval tv = { 0, 0 };
2877 if (!vd->non_adaptive) {
2878 gettimeofday(&tv, NULL);
2879 has_dirty = vnc_update_stats(vd, &tv);
2883 * Walk through the guest dirty map.
2884 * Check and copy modified bits from guest to server surface.
2885 * Update server dirty map.
2887 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2888 server_stride = guest_stride = guest_ll =
2889 pixman_image_get_stride(vd->server);
2890 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2891 server_stride);
2892 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2893 int width = pixman_image_get_width(vd->server);
2894 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2895 } else {
2896 int guest_bpp =
2897 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2898 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2899 guest_stride = pixman_image_get_stride(vd->guest.fb);
2900 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2902 line_bytes = MIN(server_stride, guest_ll);
2904 for (;;) {
2905 int x;
2906 uint8_t *guest_ptr, *server_ptr;
2907 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2908 height * VNC_DIRTY_BPL(&vd->guest),
2909 y * VNC_DIRTY_BPL(&vd->guest));
2910 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2911 /* no more dirty bits */
2912 break;
2914 y = offset / VNC_DIRTY_BPL(&vd->guest);
2915 x = offset % VNC_DIRTY_BPL(&vd->guest);
2917 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2919 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2920 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2921 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2922 } else {
2923 guest_ptr = guest_row0 + y * guest_stride;
2925 guest_ptr += x * cmp_bytes;
2927 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2928 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2929 int _cmp_bytes = cmp_bytes;
2930 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2931 continue;
2933 if ((x + 1) * cmp_bytes > line_bytes) {
2934 _cmp_bytes = line_bytes - x * cmp_bytes;
2936 assert(_cmp_bytes >= 0);
2937 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2938 continue;
2940 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2941 if (!vd->non_adaptive) {
2942 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2943 y, &tv);
2945 QTAILQ_FOREACH(vs, &vd->clients, next) {
2946 set_bit(x, vs->dirty[y]);
2948 has_dirty++;
2951 y++;
2953 qemu_pixman_image_unref(tmpbuf);
2954 return has_dirty;
2957 static void vnc_refresh(DisplayChangeListener *dcl)
2959 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2960 VncState *vs, *vn;
2961 int has_dirty, rects = 0;
2963 if (QTAILQ_EMPTY(&vd->clients)) {
2964 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2965 return;
2968 graphic_hw_update(vd->dcl.con);
2970 if (vnc_trylock_display(vd)) {
2971 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2972 return;
2975 has_dirty = vnc_refresh_server_surface(vd);
2976 vnc_unlock_display(vd);
2978 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2979 rects += vnc_update_client(vs, has_dirty, false);
2980 /* vs might be free()ed here */
2983 if (has_dirty && rects) {
2984 vd->dcl.update_interval /= 2;
2985 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2986 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2988 } else {
2989 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2990 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2991 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2996 static void vnc_connect(VncDisplay *vd, int csock,
2997 bool skipauth, bool websocket)
2999 VncState *vs = g_malloc0(sizeof(VncState));
3000 int i;
3002 vs->csock = csock;
3003 vs->vd = vd;
3005 buffer_init(&vs->input, "vnc-input/%d", csock);
3006 buffer_init(&vs->output, "vnc-output/%d", csock);
3007 buffer_init(&vs->ws_input, "vnc-ws_input/%d", csock);
3008 buffer_init(&vs->ws_output, "vnc-ws_output/%d", csock);
3009 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%d", csock);
3011 buffer_init(&vs->tight.tight, "vnc-tight/%d", csock);
3012 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%d", csock);
3013 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%d", csock);
3014 #ifdef CONFIG_VNC_JPEG
3015 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%d", csock);
3016 #endif
3017 #ifdef CONFIG_VNC_PNG
3018 buffer_init(&vs->tight.png, "vnc-tight-png/%d", csock);
3019 #endif
3020 buffer_init(&vs->zlib.zlib, "vnc-zlib/%d", csock);
3021 buffer_init(&vs->zrle.zrle, "vnc-zrle/%d", csock);
3022 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%d", csock);
3023 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%d", csock);
3025 if (skipauth) {
3026 vs->auth = VNC_AUTH_NONE;
3027 vs->subauth = VNC_AUTH_INVALID;
3028 } else {
3029 if (websocket) {
3030 vs->auth = vd->ws_auth;
3031 vs->subauth = VNC_AUTH_INVALID;
3032 } else {
3033 vs->auth = vd->auth;
3034 vs->subauth = vd->subauth;
3037 VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
3038 csock, websocket, vs->auth, vs->subauth);
3040 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3041 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3042 vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));
3045 VNC_DEBUG("New client on socket %d\n", csock);
3046 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3047 qemu_set_nonblock(vs->csock);
3048 if (websocket) {
3049 vs->websocket = 1;
3050 if (vd->ws_tls) {
3051 qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io, NULL, vs);
3052 } else {
3053 qemu_set_fd_handler(vs->csock, vncws_handshake_read, NULL, vs);
3055 } else
3057 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
3060 vnc_client_cache_addr(vs);
3061 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3062 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3064 if (!vs->websocket) {
3065 vnc_init_state(vs);
3068 if (vd->num_connecting > vd->connections_limit) {
3069 QTAILQ_FOREACH(vs, &vd->clients, next) {
3070 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3071 vnc_disconnect_start(vs);
3072 return;
3078 void vnc_init_state(VncState *vs)
3080 vs->initialized = true;
3081 VncDisplay *vd = vs->vd;
3083 vs->last_x = -1;
3084 vs->last_y = -1;
3086 vs->as.freq = 44100;
3087 vs->as.nchannels = 2;
3088 vs->as.fmt = AUD_FMT_S16;
3089 vs->as.endianness = 0;
3091 qemu_mutex_init(&vs->output_mutex);
3092 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3094 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3096 graphic_hw_update(vd->dcl.con);
3098 vnc_write(vs, "RFB 003.008\n", 12);
3099 vnc_flush(vs);
3100 vnc_read_when(vs, protocol_version, 12);
3101 reset_keys(vs);
3102 if (vs->vd->lock_key_sync)
3103 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3105 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3106 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3108 /* vs might be free()ed here */
3111 static void vnc_listen_read(void *opaque, bool websocket)
3113 VncDisplay *vs = opaque;
3114 struct sockaddr_in addr;
3115 socklen_t addrlen = sizeof(addr);
3116 int csock;
3118 /* Catch-up */
3119 graphic_hw_update(vs->dcl.con);
3120 if (websocket) {
3121 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
3122 } else {
3123 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
3126 if (csock != -1) {
3127 socket_set_nodelay(csock);
3128 vnc_connect(vs, csock, false, websocket);
3132 static void vnc_listen_regular_read(void *opaque)
3134 vnc_listen_read(opaque, false);
3137 static void vnc_listen_websocket_read(void *opaque)
3139 vnc_listen_read(opaque, true);
3142 static const DisplayChangeListenerOps dcl_ops = {
3143 .dpy_name = "vnc",
3144 .dpy_refresh = vnc_refresh,
3145 .dpy_gfx_copy = vnc_dpy_copy,
3146 .dpy_gfx_update = vnc_dpy_update,
3147 .dpy_gfx_switch = vnc_dpy_switch,
3148 .dpy_gfx_check_format = qemu_pixman_check_format,
3149 .dpy_mouse_set = vnc_mouse_set,
3150 .dpy_cursor_define = vnc_dpy_cursor_define,
3153 void vnc_display_init(const char *id)
3155 VncDisplay *vs;
3157 if (vnc_display_find(id) != NULL) {
3158 return;
3160 vs = g_malloc0(sizeof(*vs));
3162 vs->id = strdup(id);
3163 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3165 vs->lsock = -1;
3166 vs->lwebsock = -1;
3168 QTAILQ_INIT(&vs->clients);
3169 vs->expires = TIME_MAX;
3171 if (keyboard_layout) {
3172 trace_vnc_key_map_init(keyboard_layout);
3173 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3174 } else {
3175 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3178 if (!vs->kbd_layout)
3179 exit(1);
3181 qemu_mutex_init(&vs->mutex);
3182 vnc_start_worker_thread();
3184 vs->dcl.ops = &dcl_ops;
3185 register_displaychangelistener(&vs->dcl);
3189 static void vnc_display_close(VncDisplay *vs)
3191 if (!vs)
3192 return;
3193 vs->enabled = false;
3194 vs->is_unix = false;
3195 if (vs->lsock != -1) {
3196 qemu_set_fd_handler(vs->lsock, NULL, NULL, NULL);
3197 close(vs->lsock);
3198 vs->lsock = -1;
3200 vs->ws_enabled = false;
3201 if (vs->lwebsock != -1) {
3202 qemu_set_fd_handler(vs->lwebsock, NULL, NULL, NULL);
3203 close(vs->lwebsock);
3204 vs->lwebsock = -1;
3206 vs->auth = VNC_AUTH_INVALID;
3207 vs->subauth = VNC_AUTH_INVALID;
3208 if (vs->tlscreds) {
3209 object_unparent(OBJECT(vs->tlscreds));
3211 g_free(vs->tlsaclname);
3212 vs->tlsaclname = NULL;
3215 int vnc_display_password(const char *id, const char *password)
3217 VncDisplay *vs = vnc_display_find(id);
3219 if (!vs) {
3220 return -EINVAL;
3222 if (vs->auth == VNC_AUTH_NONE) {
3223 error_printf_unless_qmp("If you want use passwords please enable "
3224 "password auth using '-vnc ${dpy},password'.");
3225 return -EINVAL;
3228 g_free(vs->password);
3229 vs->password = g_strdup(password);
3231 return 0;
3234 int vnc_display_pw_expire(const char *id, time_t expires)
3236 VncDisplay *vs = vnc_display_find(id);
3238 if (!vs) {
3239 return -EINVAL;
3242 vs->expires = expires;
3243 return 0;
3246 char *vnc_display_local_addr(const char *id)
3248 VncDisplay *vs = vnc_display_find(id);
3250 assert(vs);
3251 return vnc_socket_local_addr("%s:%s", vs->lsock);
3254 static QemuOptsList qemu_vnc_opts = {
3255 .name = "vnc",
3256 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3257 .implied_opt_name = "vnc",
3258 .desc = {
3260 .name = "vnc",
3261 .type = QEMU_OPT_STRING,
3263 .name = "websocket",
3264 .type = QEMU_OPT_STRING,
3266 .name = "tls-creds",
3267 .type = QEMU_OPT_STRING,
3269 /* Deprecated in favour of tls-creds */
3270 .name = "x509",
3271 .type = QEMU_OPT_STRING,
3273 .name = "share",
3274 .type = QEMU_OPT_STRING,
3276 .name = "display",
3277 .type = QEMU_OPT_STRING,
3279 .name = "head",
3280 .type = QEMU_OPT_NUMBER,
3282 .name = "connections",
3283 .type = QEMU_OPT_NUMBER,
3285 .name = "to",
3286 .type = QEMU_OPT_NUMBER,
3288 .name = "ipv4",
3289 .type = QEMU_OPT_BOOL,
3291 .name = "ipv6",
3292 .type = QEMU_OPT_BOOL,
3294 .name = "password",
3295 .type = QEMU_OPT_BOOL,
3297 .name = "reverse",
3298 .type = QEMU_OPT_BOOL,
3300 .name = "lock-key-sync",
3301 .type = QEMU_OPT_BOOL,
3303 .name = "sasl",
3304 .type = QEMU_OPT_BOOL,
3306 /* Deprecated in favour of tls-creds */
3307 .name = "tls",
3308 .type = QEMU_OPT_BOOL,
3310 /* Deprecated in favour of tls-creds */
3311 .name = "x509verify",
3312 .type = QEMU_OPT_STRING,
3314 .name = "acl",
3315 .type = QEMU_OPT_BOOL,
3317 .name = "lossy",
3318 .type = QEMU_OPT_BOOL,
3320 .name = "non-adaptive",
3321 .type = QEMU_OPT_BOOL,
3323 { /* end of list */ }
3328 static int
3329 vnc_display_setup_auth(VncDisplay *vs,
3330 bool password,
3331 bool sasl,
3332 bool websocket,
3333 Error **errp)
3336 * We have a choice of 3 authentication options
3338 * 1. none
3339 * 2. vnc
3340 * 3. sasl
3342 * The channel can be run in 2 modes
3344 * 1. clear
3345 * 2. tls
3347 * And TLS can use 2 types of credentials
3349 * 1. anon
3350 * 2. x509
3352 * We thus have 9 possible logical combinations
3354 * 1. clear + none
3355 * 2. clear + vnc
3356 * 3. clear + sasl
3357 * 4. tls + anon + none
3358 * 5. tls + anon + vnc
3359 * 6. tls + anon + sasl
3360 * 7. tls + x509 + none
3361 * 8. tls + x509 + vnc
3362 * 9. tls + x509 + sasl
3364 * These need to be mapped into the VNC auth schemes
3365 * in an appropriate manner. In regular VNC, all the
3366 * TLS options get mapped into VNC_AUTH_VENCRYPT
3367 * sub-auth types.
3369 * In websockets, the https:// protocol already provides
3370 * TLS support, so there is no need to make use of the
3371 * VeNCrypt extension. Furthermore, websockets browser
3372 * clients could not use VeNCrypt even if they wanted to,
3373 * as they cannot control when the TLS handshake takes
3374 * place. Thus there is no option but to rely on https://,
3375 * meaning combinations 4->6 and 7->9 will be mapped to
3376 * VNC auth schemes in the same way as combos 1->3.
3378 * Regardless of fact that we have a different mapping to
3379 * VNC auth mechs for plain VNC vs websockets VNC, the end
3380 * result has the same security characteristics.
3382 if (password) {
3383 if (vs->tlscreds) {
3384 vs->auth = VNC_AUTH_VENCRYPT;
3385 if (websocket) {
3386 vs->ws_tls = true;
3388 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3389 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3390 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3391 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3392 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3393 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3394 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3395 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3396 } else {
3397 error_setg(errp,
3398 "Unsupported TLS cred type %s",
3399 object_get_typename(OBJECT(vs->tlscreds)));
3400 return -1;
3402 } else {
3403 VNC_DEBUG("Initializing VNC server with password auth\n");
3404 vs->auth = VNC_AUTH_VNC;
3405 vs->subauth = VNC_AUTH_INVALID;
3407 if (websocket) {
3408 vs->ws_auth = VNC_AUTH_VNC;
3409 } else {
3410 vs->ws_auth = VNC_AUTH_INVALID;
3412 } else if (sasl) {
3413 if (vs->tlscreds) {
3414 vs->auth = VNC_AUTH_VENCRYPT;
3415 if (websocket) {
3416 vs->ws_tls = true;
3418 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3419 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3420 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3421 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3422 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3423 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3424 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3425 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3426 } else {
3427 error_setg(errp,
3428 "Unsupported TLS cred type %s",
3429 object_get_typename(OBJECT(vs->tlscreds)));
3430 return -1;
3432 } else {
3433 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3434 vs->auth = VNC_AUTH_SASL;
3435 vs->subauth = VNC_AUTH_INVALID;
3437 if (websocket) {
3438 vs->ws_auth = VNC_AUTH_SASL;
3439 } else {
3440 vs->ws_auth = VNC_AUTH_INVALID;
3442 } else {
3443 if (vs->tlscreds) {
3444 vs->auth = VNC_AUTH_VENCRYPT;
3445 if (websocket) {
3446 vs->ws_tls = true;
3448 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3449 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3450 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3451 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3452 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3453 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3454 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3455 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3456 } else {
3457 error_setg(errp,
3458 "Unsupported TLS cred type %s",
3459 object_get_typename(OBJECT(vs->tlscreds)));
3460 return -1;
3462 } else {
3463 VNC_DEBUG("Initializing VNC server with no auth\n");
3464 vs->auth = VNC_AUTH_NONE;
3465 vs->subauth = VNC_AUTH_INVALID;
3467 if (websocket) {
3468 vs->ws_auth = VNC_AUTH_NONE;
3469 } else {
3470 vs->ws_auth = VNC_AUTH_INVALID;
3473 return 0;
3478 * Handle back compat with old CLI syntax by creating some
3479 * suitable QCryptoTLSCreds objects
3481 static QCryptoTLSCreds *
3482 vnc_display_create_creds(bool x509,
3483 bool x509verify,
3484 const char *dir,
3485 const char *id,
3486 Error **errp)
3488 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3489 Object *parent = object_get_objects_root();
3490 Object *creds;
3491 Error *err = NULL;
3493 if (x509) {
3494 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3495 parent,
3496 credsid,
3497 &err,
3498 "endpoint", "server",
3499 "dir", dir,
3500 "verify-peer", x509verify ? "yes" : "no",
3501 NULL);
3502 } else {
3503 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3504 parent,
3505 credsid,
3506 &err,
3507 "endpoint", "server",
3508 NULL);
3511 g_free(credsid);
3513 if (err) {
3514 error_propagate(errp, err);
3515 return NULL;
3518 return QCRYPTO_TLS_CREDS(creds);
3522 void vnc_display_open(const char *id, Error **errp)
3524 VncDisplay *vs = vnc_display_find(id);
3525 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3526 SocketAddress *saddr = NULL, *wsaddr = NULL;
3527 const char *share, *device_id;
3528 QemuConsole *con;
3529 bool password = false;
3530 bool reverse = false;
3531 const char *vnc;
3532 char *h;
3533 const char *credid;
3534 bool sasl = false;
3535 #ifdef CONFIG_VNC_SASL
3536 int saslErr;
3537 #endif
3538 int acl = 0;
3539 int lock_key_sync = 1;
3541 if (!vs) {
3542 error_setg(errp, "VNC display not active");
3543 return;
3545 vnc_display_close(vs);
3547 if (!opts) {
3548 return;
3550 vnc = qemu_opt_get(opts, "vnc");
3551 if (!vnc || strcmp(vnc, "none") == 0) {
3552 return;
3555 h = strrchr(vnc, ':');
3556 if (h) {
3557 size_t hlen = h - vnc;
3559 const char *websocket = qemu_opt_get(opts, "websocket");
3560 int to = qemu_opt_get_number(opts, "to", 0);
3561 bool has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3562 bool has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3564 saddr = g_new0(SocketAddress, 1);
3565 if (websocket) {
3566 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3567 error_setg(errp,
3568 "SHA1 hash support is required for websockets");
3569 goto fail;
3572 wsaddr = g_new0(SocketAddress, 1);
3573 vs->ws_enabled = true;
3576 if (strncmp(vnc, "unix:", 5) == 0) {
3577 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
3578 saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
3579 saddr->u.q_unix->path = g_strdup(vnc + 5);
3581 if (vs->ws_enabled) {
3582 error_setg(errp, "UNIX sockets not supported with websock");
3583 goto fail;
3585 } else {
3586 unsigned long long baseport;
3587 saddr->type = SOCKET_ADDRESS_KIND_INET;
3588 saddr->u.inet = g_new0(InetSocketAddress, 1);
3589 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3590 saddr->u.inet->host = g_strndup(vnc + 1, hlen - 2);
3591 } else {
3592 saddr->u.inet->host = g_strndup(vnc, hlen);
3594 if (parse_uint_full(h + 1, &baseport, 10) < 0) {
3595 error_setg(errp, "can't convert to a number: %s", h + 1);
3596 goto fail;
3598 if (baseport > 65535 ||
3599 baseport + 5900 > 65535) {
3600 error_setg(errp, "port %s out of range", h + 1);
3601 goto fail;
3603 saddr->u.inet->port = g_strdup_printf(
3604 "%d", (int)baseport + 5900);
3606 if (to) {
3607 saddr->u.inet->has_to = true;
3608 saddr->u.inet->to = to;
3609 saddr->u.inet->has_to = true;
3610 saddr->u.inet->to = to + 5900;
3612 saddr->u.inet->ipv4 = saddr->u.inet->has_ipv4 = has_ipv4;
3613 saddr->u.inet->ipv6 = saddr->u.inet->has_ipv6 = has_ipv6;
3615 if (vs->ws_enabled) {
3616 wsaddr->type = SOCKET_ADDRESS_KIND_INET;
3617 wsaddr->u.inet = g_new0(InetSocketAddress, 1);
3618 wsaddr->u.inet->host = g_strdup(saddr->u.inet->host);
3619 wsaddr->u.inet->port = g_strdup(websocket);
3621 if (to) {
3622 wsaddr->u.inet->has_to = true;
3623 wsaddr->u.inet->to = to;
3625 wsaddr->u.inet->ipv4 = wsaddr->u.inet->has_ipv4 = has_ipv4;
3626 wsaddr->u.inet->ipv6 = wsaddr->u.inet->has_ipv6 = has_ipv6;
3629 } else {
3630 error_setg(errp, "no vnc port specified");
3631 goto fail;
3634 password = qemu_opt_get_bool(opts, "password", false);
3635 if (password) {
3636 if (fips_get_state()) {
3637 error_setg(errp,
3638 "VNC password auth disabled due to FIPS mode, "
3639 "consider using the VeNCrypt or SASL authentication "
3640 "methods as an alternative");
3641 goto fail;
3643 if (!qcrypto_cipher_supports(
3644 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3645 error_setg(errp,
3646 "Cipher backend does not support DES RFB algorithm");
3647 goto fail;
3651 reverse = qemu_opt_get_bool(opts, "reverse", false);
3652 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3653 sasl = qemu_opt_get_bool(opts, "sasl", false);
3654 #ifndef CONFIG_VNC_SASL
3655 if (sasl) {
3656 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3657 goto fail;
3659 #endif /* CONFIG_VNC_SASL */
3660 credid = qemu_opt_get(opts, "tls-creds");
3661 if (credid) {
3662 Object *creds;
3663 if (qemu_opt_get(opts, "tls") ||
3664 qemu_opt_get(opts, "x509") ||
3665 qemu_opt_get(opts, "x509verify")) {
3666 error_setg(errp,
3667 "'credid' parameter is mutually exclusive with "
3668 "'tls', 'x509' and 'x509verify' parameters");
3669 goto fail;
3672 creds = object_resolve_path_component(
3673 object_get_objects_root(), credid);
3674 if (!creds) {
3675 error_setg(errp, "No TLS credentials with id '%s'",
3676 credid);
3677 goto fail;
3679 vs->tlscreds = (QCryptoTLSCreds *)
3680 object_dynamic_cast(creds,
3681 TYPE_QCRYPTO_TLS_CREDS);
3682 if (!vs->tlscreds) {
3683 error_setg(errp, "Object with id '%s' is not TLS credentials",
3684 credid);
3685 goto fail;
3687 object_ref(OBJECT(vs->tlscreds));
3689 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3690 error_setg(errp,
3691 "Expecting TLS credentials with a server endpoint");
3692 goto fail;
3694 } else {
3695 const char *path;
3696 bool tls = false, x509 = false, x509verify = false;
3697 tls = qemu_opt_get_bool(opts, "tls", false);
3698 if (tls) {
3699 path = qemu_opt_get(opts, "x509");
3701 if (path) {
3702 x509 = true;
3703 } else {
3704 path = qemu_opt_get(opts, "x509verify");
3705 if (path) {
3706 x509 = true;
3707 x509verify = true;
3710 vs->tlscreds = vnc_display_create_creds(x509,
3711 x509verify,
3712 path,
3713 vs->id,
3714 errp);
3715 if (!vs->tlscreds) {
3716 goto fail;
3720 acl = qemu_opt_get_bool(opts, "acl", false);
3722 share = qemu_opt_get(opts, "share");
3723 if (share) {
3724 if (strcmp(share, "ignore") == 0) {
3725 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3726 } else if (strcmp(share, "allow-exclusive") == 0) {
3727 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3728 } else if (strcmp(share, "force-shared") == 0) {
3729 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3730 } else {
3731 error_setg(errp, "unknown vnc share= option");
3732 goto fail;
3734 } else {
3735 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3737 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3739 #ifdef CONFIG_VNC_JPEG
3740 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3741 #endif
3742 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3743 /* adaptive updates are only used with tight encoding and
3744 * if lossy updates are enabled so we can disable all the
3745 * calculations otherwise */
3746 if (!vs->lossy) {
3747 vs->non_adaptive = true;
3750 if (acl) {
3751 if (strcmp(vs->id, "default") == 0) {
3752 vs->tlsaclname = g_strdup("vnc.x509dname");
3753 } else {
3754 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3756 qemu_acl_init(vs->tlsaclname);
3758 #ifdef CONFIG_VNC_SASL
3759 if (acl && sasl) {
3760 char *aclname;
3762 if (strcmp(vs->id, "default") == 0) {
3763 aclname = g_strdup("vnc.username");
3764 } else {
3765 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3767 vs->sasl.acl = qemu_acl_init(aclname);
3768 g_free(aclname);
3770 #endif
3772 if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
3773 goto fail;
3776 #ifdef CONFIG_VNC_SASL
3777 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3778 error_setg(errp, "Failed to initialize SASL auth: %s",
3779 sasl_errstring(saslErr, NULL, NULL));
3780 goto fail;
3782 #endif
3783 vs->lock_key_sync = lock_key_sync;
3785 device_id = qemu_opt_get(opts, "display");
3786 if (device_id) {
3787 DeviceState *dev;
3788 int head = qemu_opt_get_number(opts, "head", 0);
3790 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3791 if (dev == NULL) {
3792 error_setg(errp, "Device '%s' not found", device_id);
3793 goto fail;
3796 con = qemu_console_lookup_by_device(dev, head);
3797 if (con == NULL) {
3798 error_setg(errp, "Device %s is not bound to a QemuConsole",
3799 device_id);
3800 goto fail;
3802 } else {
3803 con = NULL;
3806 if (con != vs->dcl.con) {
3807 unregister_displaychangelistener(&vs->dcl);
3808 vs->dcl.con = con;
3809 register_displaychangelistener(&vs->dcl);
3812 if (reverse) {
3813 /* connect to viewer */
3814 int csock;
3815 vs->lsock = -1;
3816 vs->lwebsock = -1;
3817 if (vs->ws_enabled) {
3818 error_setg(errp, "Cannot use websockets in reverse mode");
3819 goto fail;
3821 csock = socket_connect(saddr, errp, NULL, NULL);
3822 if (csock < 0) {
3823 goto fail;
3825 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3826 vnc_connect(vs, csock, false, false);
3827 } else {
3828 /* listen for connects */
3829 vs->lsock = socket_listen(saddr, errp);
3830 if (vs->lsock < 0) {
3831 goto fail;
3833 vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
3834 if (vs->ws_enabled) {
3835 vs->lwebsock = socket_listen(wsaddr, errp);
3836 if (vs->lwebsock < 0) {
3837 if (vs->lsock != -1) {
3838 close(vs->lsock);
3839 vs->lsock = -1;
3841 goto fail;
3844 vs->enabled = true;
3845 qemu_set_fd_handler(vs->lsock, vnc_listen_regular_read, NULL, vs);
3846 if (vs->ws_enabled) {
3847 qemu_set_fd_handler(vs->lwebsock, vnc_listen_websocket_read,
3848 NULL, vs);
3852 qapi_free_SocketAddress(saddr);
3853 qapi_free_SocketAddress(wsaddr);
3854 return;
3856 fail:
3857 qapi_free_SocketAddress(saddr);
3858 qapi_free_SocketAddress(wsaddr);
3859 vs->enabled = false;
3860 vs->ws_enabled = false;
3863 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3865 VncDisplay *vs = vnc_display_find(id);
3867 if (!vs) {
3868 return;
3870 vnc_connect(vs, csock, skipauth, false);
3873 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3875 int i = 2;
3876 char *id;
3878 id = g_strdup("default");
3879 while (qemu_opts_find(olist, id)) {
3880 g_free(id);
3881 id = g_strdup_printf("vnc%d", i++);
3883 qemu_opts_set_id(opts, id);
3886 QemuOpts *vnc_parse(const char *str, Error **errp)
3888 QemuOptsList *olist = qemu_find_opts("vnc");
3889 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3890 const char *id;
3892 if (!opts) {
3893 return NULL;
3896 id = qemu_opts_id(opts);
3897 if (!id) {
3898 /* auto-assign id if not present */
3899 vnc_auto_assign_id(olist, opts);
3901 return opts;
3904 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3906 Error *local_err = NULL;
3907 char *id = (char *)qemu_opts_id(opts);
3909 assert(id);
3910 vnc_display_init(id);
3911 vnc_display_open(id, &local_err);
3912 if (local_err != NULL) {
3913 error_report("Failed to start VNC server: %s",
3914 error_get_pretty(local_err));
3915 error_free(local_err);
3916 exit(1);
3918 return 0;
3921 static void vnc_register_config(void)
3923 qemu_add_opts(&qemu_vnc_opts);
3925 machine_init(vnc_register_config);