vfio/pci: Cleanup Nvidia 0x3d0 quirk
[qemu/ar7.git] / ui / vnc.c
blobd73966afc56e4d9797f8d6bd3a712d88cc60d241
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 VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
160 socklen_t salen)
162 VncBasicInfo *info;
163 char host[NI_MAXHOST];
164 char serv[NI_MAXSERV];
165 int err;
167 if ((err = getnameinfo((struct sockaddr *)sa, salen,
168 host, sizeof(host),
169 serv, sizeof(serv),
170 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
171 VNC_DEBUG("Cannot resolve address %d: %s\n",
172 err, gai_strerror(err));
173 return NULL;
176 info = g_malloc0(sizeof(VncBasicInfo));
177 info->host = g_strdup(host);
178 info->service = g_strdup(serv);
179 info->family = inet_netfamily(sa->ss_family);
180 return info;
183 static VncBasicInfo *vnc_basic_info_get_from_server_addr(int fd)
185 struct sockaddr_storage sa;
186 socklen_t salen;
188 salen = sizeof(sa);
189 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
190 return NULL;
193 return vnc_basic_info_get(&sa, salen);
196 static VncBasicInfo *vnc_basic_info_get_from_remote_addr(int fd)
198 struct sockaddr_storage sa;
199 socklen_t salen;
201 salen = sizeof(sa);
202 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
203 return NULL;
206 return vnc_basic_info_get(&sa, salen);
209 static const char *vnc_auth_name(VncDisplay *vd) {
210 switch (vd->auth) {
211 case VNC_AUTH_INVALID:
212 return "invalid";
213 case VNC_AUTH_NONE:
214 return "none";
215 case VNC_AUTH_VNC:
216 return "vnc";
217 case VNC_AUTH_RA2:
218 return "ra2";
219 case VNC_AUTH_RA2NE:
220 return "ra2ne";
221 case VNC_AUTH_TIGHT:
222 return "tight";
223 case VNC_AUTH_ULTRA:
224 return "ultra";
225 case VNC_AUTH_TLS:
226 return "tls";
227 case VNC_AUTH_VENCRYPT:
228 switch (vd->subauth) {
229 case VNC_AUTH_VENCRYPT_PLAIN:
230 return "vencrypt+plain";
231 case VNC_AUTH_VENCRYPT_TLSNONE:
232 return "vencrypt+tls+none";
233 case VNC_AUTH_VENCRYPT_TLSVNC:
234 return "vencrypt+tls+vnc";
235 case VNC_AUTH_VENCRYPT_TLSPLAIN:
236 return "vencrypt+tls+plain";
237 case VNC_AUTH_VENCRYPT_X509NONE:
238 return "vencrypt+x509+none";
239 case VNC_AUTH_VENCRYPT_X509VNC:
240 return "vencrypt+x509+vnc";
241 case VNC_AUTH_VENCRYPT_X509PLAIN:
242 return "vencrypt+x509+plain";
243 case VNC_AUTH_VENCRYPT_TLSSASL:
244 return "vencrypt+tls+sasl";
245 case VNC_AUTH_VENCRYPT_X509SASL:
246 return "vencrypt+x509+sasl";
247 default:
248 return "vencrypt";
250 case VNC_AUTH_SASL:
251 return "sasl";
253 return "unknown";
256 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
258 VncServerInfo *info;
259 VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vd->lsock);
260 if (!bi) {
261 return NULL;
264 info = g_malloc(sizeof(*info));
265 info->base = bi;
266 info->has_auth = true;
267 info->auth = g_strdup(vnc_auth_name(vd));
268 return info;
271 static void vnc_client_cache_auth(VncState *client)
273 if (!client->info) {
274 return;
277 if (client->tls) {
278 client->info->x509_dname =
279 qcrypto_tls_session_get_peer_name(client->tls);
280 client->info->has_x509_dname =
281 client->info->x509_dname != NULL;
283 #ifdef CONFIG_VNC_SASL
284 if (client->sasl.conn &&
285 client->sasl.username) {
286 client->info->has_sasl_username = true;
287 client->info->sasl_username = g_strdup(client->sasl.username);
289 #endif
292 static void vnc_client_cache_addr(VncState *client)
294 VncBasicInfo *bi = vnc_basic_info_get_from_remote_addr(client->csock);
296 if (bi) {
297 client->info = g_malloc0(sizeof(*client->info));
298 client->info->base = bi;
302 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
304 VncServerInfo *si;
306 if (!vs->info) {
307 return;
309 g_assert(vs->info->base);
311 si = vnc_server_info_get(vs->vd);
312 if (!si) {
313 return;
316 switch (event) {
317 case QAPI_EVENT_VNC_CONNECTED:
318 qapi_event_send_vnc_connected(si, vs->info->base, &error_abort);
319 break;
320 case QAPI_EVENT_VNC_INITIALIZED:
321 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
322 break;
323 case QAPI_EVENT_VNC_DISCONNECTED:
324 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
325 break;
326 default:
327 break;
330 qapi_free_VncServerInfo(si);
333 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
335 struct sockaddr_storage sa;
336 socklen_t salen = sizeof(sa);
337 char host[NI_MAXHOST];
338 char serv[NI_MAXSERV];
339 VncClientInfo *info;
341 if (getpeername(client->csock, (struct sockaddr *)&sa, &salen) < 0) {
342 return NULL;
345 if (getnameinfo((struct sockaddr *)&sa, salen,
346 host, sizeof(host),
347 serv, sizeof(serv),
348 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
349 return NULL;
352 info = g_malloc0(sizeof(*info));
353 info->base = g_malloc0(sizeof(*info->base));
354 info->base->host = g_strdup(host);
355 info->base->service = g_strdup(serv);
356 info->base->family = inet_netfamily(sa.ss_family);
357 info->base->websocket = client->websocket;
359 if (client->tls) {
360 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
361 info->has_x509_dname = info->x509_dname != NULL;
363 #ifdef CONFIG_VNC_SASL
364 if (client->sasl.conn && client->sasl.username) {
365 info->has_sasl_username = true;
366 info->sasl_username = g_strdup(client->sasl.username);
368 #endif
370 return info;
373 static VncDisplay *vnc_display_find(const char *id)
375 VncDisplay *vd;
377 if (id == NULL) {
378 return QTAILQ_FIRST(&vnc_displays);
380 QTAILQ_FOREACH(vd, &vnc_displays, next) {
381 if (strcmp(id, vd->id) == 0) {
382 return vd;
385 return NULL;
388 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
390 VncClientInfoList *cinfo, *prev = NULL;
391 VncState *client;
393 QTAILQ_FOREACH(client, &vd->clients, next) {
394 cinfo = g_new0(VncClientInfoList, 1);
395 cinfo->value = qmp_query_vnc_client(client);
396 cinfo->next = prev;
397 prev = cinfo;
399 return prev;
402 VncInfo *qmp_query_vnc(Error **errp)
404 VncInfo *info = g_malloc0(sizeof(*info));
405 VncDisplay *vd = vnc_display_find(NULL);
407 if (vd == NULL || !vd->enabled) {
408 info->enabled = false;
409 } else {
410 struct sockaddr_storage sa;
411 socklen_t salen = sizeof(sa);
412 char host[NI_MAXHOST];
413 char serv[NI_MAXSERV];
415 info->enabled = true;
417 /* for compatibility with the original command */
418 info->has_clients = true;
419 info->clients = qmp_query_client_list(vd);
421 if (vd->lsock == -1) {
422 return info;
425 if (getsockname(vd->lsock, (struct sockaddr *)&sa,
426 &salen) == -1) {
427 error_setg(errp, QERR_UNDEFINED_ERROR);
428 goto out_error;
431 if (getnameinfo((struct sockaddr *)&sa, salen,
432 host, sizeof(host),
433 serv, sizeof(serv),
434 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
435 error_setg(errp, QERR_UNDEFINED_ERROR);
436 goto out_error;
439 info->has_host = true;
440 info->host = g_strdup(host);
442 info->has_service = true;
443 info->service = g_strdup(serv);
445 info->has_family = true;
446 info->family = inet_netfamily(sa.ss_family);
448 info->has_auth = true;
449 info->auth = g_strdup(vnc_auth_name(vd));
452 return info;
454 out_error:
455 qapi_free_VncInfo(info);
456 return NULL;
459 static VncBasicInfoList *qmp_query_server_entry(int socket,
460 bool websocket,
461 VncBasicInfoList *prev)
463 VncBasicInfoList *list;
464 VncBasicInfo *info;
465 struct sockaddr_storage sa;
466 socklen_t salen = sizeof(sa);
467 char host[NI_MAXHOST];
468 char serv[NI_MAXSERV];
470 if (getsockname(socket, (struct sockaddr *)&sa, &salen) < 0 ||
471 getnameinfo((struct sockaddr *)&sa, salen,
472 host, sizeof(host), serv, sizeof(serv),
473 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
474 return prev;
477 info = g_new0(VncBasicInfo, 1);
478 info->host = g_strdup(host);
479 info->service = g_strdup(serv);
480 info->family = inet_netfamily(sa.ss_family);
481 info->websocket = websocket;
483 list = g_new0(VncBasicInfoList, 1);
484 list->value = info;
485 list->next = prev;
486 return list;
489 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
491 switch (vd->auth) {
492 case VNC_AUTH_VNC:
493 info->auth = VNC_PRIMARY_AUTH_VNC;
494 break;
495 case VNC_AUTH_RA2:
496 info->auth = VNC_PRIMARY_AUTH_RA2;
497 break;
498 case VNC_AUTH_RA2NE:
499 info->auth = VNC_PRIMARY_AUTH_RA2NE;
500 break;
501 case VNC_AUTH_TIGHT:
502 info->auth = VNC_PRIMARY_AUTH_TIGHT;
503 break;
504 case VNC_AUTH_ULTRA:
505 info->auth = VNC_PRIMARY_AUTH_ULTRA;
506 break;
507 case VNC_AUTH_TLS:
508 info->auth = VNC_PRIMARY_AUTH_TLS;
509 break;
510 case VNC_AUTH_VENCRYPT:
511 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
512 info->has_vencrypt = true;
513 switch (vd->subauth) {
514 case VNC_AUTH_VENCRYPT_PLAIN:
515 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
516 break;
517 case VNC_AUTH_VENCRYPT_TLSNONE:
518 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
519 break;
520 case VNC_AUTH_VENCRYPT_TLSVNC:
521 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
522 break;
523 case VNC_AUTH_VENCRYPT_TLSPLAIN:
524 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
525 break;
526 case VNC_AUTH_VENCRYPT_X509NONE:
527 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
528 break;
529 case VNC_AUTH_VENCRYPT_X509VNC:
530 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
531 break;
532 case VNC_AUTH_VENCRYPT_X509PLAIN:
533 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
534 break;
535 case VNC_AUTH_VENCRYPT_TLSSASL:
536 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
537 break;
538 case VNC_AUTH_VENCRYPT_X509SASL:
539 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
540 break;
541 default:
542 info->has_vencrypt = false;
543 break;
545 break;
546 case VNC_AUTH_SASL:
547 info->auth = VNC_PRIMARY_AUTH_SASL;
548 break;
549 case VNC_AUTH_NONE:
550 default:
551 info->auth = VNC_PRIMARY_AUTH_NONE;
552 break;
556 VncInfo2List *qmp_query_vnc_servers(Error **errp)
558 VncInfo2List *item, *prev = NULL;
559 VncInfo2 *info;
560 VncDisplay *vd;
561 DeviceState *dev;
563 QTAILQ_FOREACH(vd, &vnc_displays, next) {
564 info = g_new0(VncInfo2, 1);
565 info->id = g_strdup(vd->id);
566 info->clients = qmp_query_client_list(vd);
567 qmp_query_auth(vd, info);
568 if (vd->dcl.con) {
569 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
570 "device", NULL));
571 info->has_display = true;
572 info->display = g_strdup(dev->id);
574 if (vd->lsock != -1) {
575 info->server = qmp_query_server_entry(vd->lsock, false,
576 info->server);
578 if (vd->lwebsock != -1) {
579 info->server = qmp_query_server_entry(vd->lwebsock, true,
580 info->server);
583 item = g_new0(VncInfo2List, 1);
584 item->value = info;
585 item->next = prev;
586 prev = item;
588 return prev;
591 /* TODO
592 1) Get the queue working for IO.
593 2) there is some weirdness when using the -S option (the screen is grey
594 and not totally invalidated
595 3) resolutions > 1024
598 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
599 static void vnc_disconnect_start(VncState *vs);
601 static void vnc_colordepth(VncState *vs);
602 static void framebuffer_update_request(VncState *vs, int incremental,
603 int x_position, int y_position,
604 int w, int h);
605 static void vnc_refresh(DisplayChangeListener *dcl);
606 static int vnc_refresh_server_surface(VncDisplay *vd);
608 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
609 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
610 int width, int height,
611 int x, int y, int w, int h) {
612 /* this is needed this to ensure we updated all affected
613 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
614 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
615 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
617 x = MIN(x, width);
618 y = MIN(y, height);
619 w = MIN(x + w, width) - x;
620 h = MIN(y + h, height);
622 for (; y < h; y++) {
623 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
624 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
628 static void vnc_dpy_update(DisplayChangeListener *dcl,
629 int x, int y, int w, int h)
631 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
632 struct VncSurface *s = &vd->guest;
633 int width = pixman_image_get_width(vd->server);
634 int height = pixman_image_get_height(vd->server);
636 vnc_set_area_dirty(s->dirty, width, height, x, y, w, h);
639 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
640 int32_t encoding)
642 vnc_write_u16(vs, x);
643 vnc_write_u16(vs, y);
644 vnc_write_u16(vs, w);
645 vnc_write_u16(vs, h);
647 vnc_write_s32(vs, encoding);
650 void buffer_reserve(Buffer *buffer, size_t len)
652 if ((buffer->capacity - buffer->offset) < len) {
653 buffer->capacity += (len + 1024);
654 buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
658 static int buffer_empty(Buffer *buffer)
660 return buffer->offset == 0;
663 uint8_t *buffer_end(Buffer *buffer)
665 return buffer->buffer + buffer->offset;
668 void buffer_reset(Buffer *buffer)
670 buffer->offset = 0;
673 void buffer_free(Buffer *buffer)
675 g_free(buffer->buffer);
676 buffer->offset = 0;
677 buffer->capacity = 0;
678 buffer->buffer = NULL;
681 void buffer_append(Buffer *buffer, const void *data, size_t len)
683 memcpy(buffer->buffer + buffer->offset, data, len);
684 buffer->offset += len;
687 void buffer_advance(Buffer *buf, size_t len)
689 memmove(buf->buffer, buf->buffer + len,
690 (buf->offset - len));
691 buf->offset -= len;
694 static void vnc_desktop_resize(VncState *vs)
696 if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
697 return;
699 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
700 vs->client_height == pixman_image_get_height(vs->vd->server)) {
701 return;
703 vs->client_width = pixman_image_get_width(vs->vd->server);
704 vs->client_height = pixman_image_get_height(vs->vd->server);
705 vnc_lock_output(vs);
706 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
707 vnc_write_u8(vs, 0);
708 vnc_write_u16(vs, 1); /* number of rects */
709 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
710 VNC_ENCODING_DESKTOPRESIZE);
711 vnc_unlock_output(vs);
712 vnc_flush(vs);
715 static void vnc_abort_display_jobs(VncDisplay *vd)
717 VncState *vs;
719 QTAILQ_FOREACH(vs, &vd->clients, next) {
720 vnc_lock_output(vs);
721 vs->abort = true;
722 vnc_unlock_output(vs);
724 QTAILQ_FOREACH(vs, &vd->clients, next) {
725 vnc_jobs_join(vs);
727 QTAILQ_FOREACH(vs, &vd->clients, next) {
728 vnc_lock_output(vs);
729 vs->abort = false;
730 vnc_unlock_output(vs);
734 int vnc_server_fb_stride(VncDisplay *vd)
736 return pixman_image_get_stride(vd->server);
739 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
741 uint8_t *ptr;
743 ptr = (uint8_t *)pixman_image_get_data(vd->server);
744 ptr += y * vnc_server_fb_stride(vd);
745 ptr += x * VNC_SERVER_FB_BYTES;
746 return ptr;
749 static void vnc_dpy_switch(DisplayChangeListener *dcl,
750 DisplaySurface *surface)
752 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
753 VncState *vs;
754 int width, height;
756 vnc_abort_display_jobs(vd);
758 /* server surface */
759 qemu_pixman_image_unref(vd->server);
760 vd->ds = surface;
761 width = MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
762 VNC_DIRTY_PIXELS_PER_BIT));
763 height = MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
764 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
765 width, height, NULL, 0);
767 /* guest surface */
768 #if 0 /* FIXME */
769 if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
770 console_color_init(ds);
771 #endif
772 qemu_pixman_image_unref(vd->guest.fb);
773 vd->guest.fb = pixman_image_ref(surface->image);
774 vd->guest.format = surface->format;
775 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
776 vnc_set_area_dirty(vd->guest.dirty, width, height, 0, 0,
777 width, height);
779 QTAILQ_FOREACH(vs, &vd->clients, next) {
780 vnc_colordepth(vs);
781 vnc_desktop_resize(vs);
782 if (vs->vd->cursor) {
783 vnc_cursor_define(vs);
785 memset(vs->dirty, 0x00, sizeof(vs->dirty));
786 vnc_set_area_dirty(vs->dirty, width, height, 0, 0,
787 width, height);
791 /* fastest code */
792 static void vnc_write_pixels_copy(VncState *vs,
793 void *pixels, int size)
795 vnc_write(vs, pixels, size);
798 /* slowest but generic code. */
799 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
801 uint8_t r, g, b;
803 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
804 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
805 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
806 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
807 #else
808 # error need some bits here if you change VNC_SERVER_FB_FORMAT
809 #endif
810 v = (r << vs->client_pf.rshift) |
811 (g << vs->client_pf.gshift) |
812 (b << vs->client_pf.bshift);
813 switch (vs->client_pf.bytes_per_pixel) {
814 case 1:
815 buf[0] = v;
816 break;
817 case 2:
818 if (vs->client_be) {
819 buf[0] = v >> 8;
820 buf[1] = v;
821 } else {
822 buf[1] = v >> 8;
823 buf[0] = v;
825 break;
826 default:
827 case 4:
828 if (vs->client_be) {
829 buf[0] = v >> 24;
830 buf[1] = v >> 16;
831 buf[2] = v >> 8;
832 buf[3] = v;
833 } else {
834 buf[3] = v >> 24;
835 buf[2] = v >> 16;
836 buf[1] = v >> 8;
837 buf[0] = v;
839 break;
843 static void vnc_write_pixels_generic(VncState *vs,
844 void *pixels1, int size)
846 uint8_t buf[4];
848 if (VNC_SERVER_FB_BYTES == 4) {
849 uint32_t *pixels = pixels1;
850 int n, i;
851 n = size >> 2;
852 for (i = 0; i < n; i++) {
853 vnc_convert_pixel(vs, buf, pixels[i]);
854 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
859 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
861 int i;
862 uint8_t *row;
863 VncDisplay *vd = vs->vd;
865 row = vnc_server_fb_ptr(vd, x, y);
866 for (i = 0; i < h; i++) {
867 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
868 row += vnc_server_fb_stride(vd);
870 return 1;
873 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
875 int n = 0;
877 switch(vs->vnc_encoding) {
878 case VNC_ENCODING_ZLIB:
879 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
880 break;
881 case VNC_ENCODING_HEXTILE:
882 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
883 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
884 break;
885 case VNC_ENCODING_TIGHT:
886 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
887 break;
888 case VNC_ENCODING_TIGHT_PNG:
889 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
890 break;
891 case VNC_ENCODING_ZRLE:
892 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
893 break;
894 case VNC_ENCODING_ZYWRLE:
895 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
896 break;
897 default:
898 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
899 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
900 break;
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 int width = pixman_image_get_width(vs->vd->server);
2027 int height = pixman_image_get_height(vs->vd->server);
2029 vs->need_update = 1;
2031 if (incremental) {
2032 return;
2035 vs->force_update = 1;
2036 vnc_set_area_dirty(vs->dirty, width, height, x, y, w, h);
2039 static void send_ext_key_event_ack(VncState *vs)
2041 vnc_lock_output(vs);
2042 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2043 vnc_write_u8(vs, 0);
2044 vnc_write_u16(vs, 1);
2045 vnc_framebuffer_update(vs, 0, 0,
2046 pixman_image_get_width(vs->vd->server),
2047 pixman_image_get_height(vs->vd->server),
2048 VNC_ENCODING_EXT_KEY_EVENT);
2049 vnc_unlock_output(vs);
2050 vnc_flush(vs);
2053 static void send_ext_audio_ack(VncState *vs)
2055 vnc_lock_output(vs);
2056 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2057 vnc_write_u8(vs, 0);
2058 vnc_write_u16(vs, 1);
2059 vnc_framebuffer_update(vs, 0, 0,
2060 pixman_image_get_width(vs->vd->server),
2061 pixman_image_get_height(vs->vd->server),
2062 VNC_ENCODING_AUDIO);
2063 vnc_unlock_output(vs);
2064 vnc_flush(vs);
2067 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2069 int i;
2070 unsigned int enc = 0;
2072 vs->features = 0;
2073 vs->vnc_encoding = 0;
2074 vs->tight.compression = 9;
2075 vs->tight.quality = -1; /* Lossless by default */
2076 vs->absolute = -1;
2079 * Start from the end because the encodings are sent in order of preference.
2080 * This way the preferred encoding (first encoding defined in the array)
2081 * will be set at the end of the loop.
2083 for (i = n_encodings - 1; i >= 0; i--) {
2084 enc = encodings[i];
2085 switch (enc) {
2086 case VNC_ENCODING_RAW:
2087 vs->vnc_encoding = enc;
2088 break;
2089 case VNC_ENCODING_COPYRECT:
2090 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2091 break;
2092 case VNC_ENCODING_HEXTILE:
2093 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2094 vs->vnc_encoding = enc;
2095 break;
2096 case VNC_ENCODING_TIGHT:
2097 vs->features |= VNC_FEATURE_TIGHT_MASK;
2098 vs->vnc_encoding = enc;
2099 break;
2100 #ifdef CONFIG_VNC_PNG
2101 case VNC_ENCODING_TIGHT_PNG:
2102 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2103 vs->vnc_encoding = enc;
2104 break;
2105 #endif
2106 case VNC_ENCODING_ZLIB:
2107 vs->features |= VNC_FEATURE_ZLIB_MASK;
2108 vs->vnc_encoding = enc;
2109 break;
2110 case VNC_ENCODING_ZRLE:
2111 vs->features |= VNC_FEATURE_ZRLE_MASK;
2112 vs->vnc_encoding = enc;
2113 break;
2114 case VNC_ENCODING_ZYWRLE:
2115 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2116 vs->vnc_encoding = enc;
2117 break;
2118 case VNC_ENCODING_DESKTOPRESIZE:
2119 vs->features |= VNC_FEATURE_RESIZE_MASK;
2120 break;
2121 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2122 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2123 break;
2124 case VNC_ENCODING_RICH_CURSOR:
2125 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2126 break;
2127 case VNC_ENCODING_EXT_KEY_EVENT:
2128 send_ext_key_event_ack(vs);
2129 break;
2130 case VNC_ENCODING_AUDIO:
2131 send_ext_audio_ack(vs);
2132 break;
2133 case VNC_ENCODING_WMVi:
2134 vs->features |= VNC_FEATURE_WMVI_MASK;
2135 break;
2136 case VNC_ENCODING_LED_STATE:
2137 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2138 break;
2139 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2140 vs->tight.compression = (enc & 0x0F);
2141 break;
2142 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2143 if (vs->vd->lossy) {
2144 vs->tight.quality = (enc & 0x0F);
2146 break;
2147 default:
2148 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2149 break;
2152 vnc_desktop_resize(vs);
2153 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2154 vnc_led_state_change(vs);
2157 static void set_pixel_conversion(VncState *vs)
2159 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2161 if (fmt == VNC_SERVER_FB_FORMAT) {
2162 vs->write_pixels = vnc_write_pixels_copy;
2163 vnc_hextile_set_pixel_conversion(vs, 0);
2164 } else {
2165 vs->write_pixels = vnc_write_pixels_generic;
2166 vnc_hextile_set_pixel_conversion(vs, 1);
2170 static void set_pixel_format(VncState *vs,
2171 int bits_per_pixel, int depth,
2172 int big_endian_flag, int true_color_flag,
2173 int red_max, int green_max, int blue_max,
2174 int red_shift, int green_shift, int blue_shift)
2176 if (!true_color_flag) {
2177 vnc_client_error(vs);
2178 return;
2181 switch (bits_per_pixel) {
2182 case 8:
2183 case 16:
2184 case 32:
2185 break;
2186 default:
2187 vnc_client_error(vs);
2188 return;
2191 vs->client_pf.rmax = red_max;
2192 vs->client_pf.rbits = hweight_long(red_max);
2193 vs->client_pf.rshift = red_shift;
2194 vs->client_pf.rmask = red_max << red_shift;
2195 vs->client_pf.gmax = green_max;
2196 vs->client_pf.gbits = hweight_long(green_max);
2197 vs->client_pf.gshift = green_shift;
2198 vs->client_pf.gmask = green_max << green_shift;
2199 vs->client_pf.bmax = blue_max;
2200 vs->client_pf.bbits = hweight_long(blue_max);
2201 vs->client_pf.bshift = blue_shift;
2202 vs->client_pf.bmask = blue_max << blue_shift;
2203 vs->client_pf.bits_per_pixel = bits_per_pixel;
2204 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2205 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2206 vs->client_be = big_endian_flag;
2208 set_pixel_conversion(vs);
2210 graphic_hw_invalidate(vs->vd->dcl.con);
2211 graphic_hw_update(vs->vd->dcl.con);
2214 static void pixel_format_message (VncState *vs) {
2215 char pad[3] = { 0, 0, 0 };
2217 vs->client_pf = qemu_default_pixelformat(32);
2219 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2220 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2222 #ifdef HOST_WORDS_BIGENDIAN
2223 vnc_write_u8(vs, 1); /* big-endian-flag */
2224 #else
2225 vnc_write_u8(vs, 0); /* big-endian-flag */
2226 #endif
2227 vnc_write_u8(vs, 1); /* true-color-flag */
2228 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2229 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2230 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2231 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2232 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2233 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2234 vnc_write(vs, pad, 3); /* padding */
2236 vnc_hextile_set_pixel_conversion(vs, 0);
2237 vs->write_pixels = vnc_write_pixels_copy;
2240 static void vnc_colordepth(VncState *vs)
2242 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2243 /* Sending a WMVi message to notify the client*/
2244 vnc_lock_output(vs);
2245 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2246 vnc_write_u8(vs, 0);
2247 vnc_write_u16(vs, 1); /* number of rects */
2248 vnc_framebuffer_update(vs, 0, 0,
2249 pixman_image_get_width(vs->vd->server),
2250 pixman_image_get_height(vs->vd->server),
2251 VNC_ENCODING_WMVi);
2252 pixel_format_message(vs);
2253 vnc_unlock_output(vs);
2254 vnc_flush(vs);
2255 } else {
2256 set_pixel_conversion(vs);
2260 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2262 int i;
2263 uint16_t limit;
2264 VncDisplay *vd = vs->vd;
2266 if (data[0] > 3) {
2267 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2270 switch (data[0]) {
2271 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2272 if (len == 1)
2273 return 20;
2275 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2276 read_u8(data, 6), read_u8(data, 7),
2277 read_u16(data, 8), read_u16(data, 10),
2278 read_u16(data, 12), read_u8(data, 14),
2279 read_u8(data, 15), read_u8(data, 16));
2280 break;
2281 case VNC_MSG_CLIENT_SET_ENCODINGS:
2282 if (len == 1)
2283 return 4;
2285 if (len == 4) {
2286 limit = read_u16(data, 2);
2287 if (limit > 0)
2288 return 4 + (limit * 4);
2289 } else
2290 limit = read_u16(data, 2);
2292 for (i = 0; i < limit; i++) {
2293 int32_t val = read_s32(data, 4 + (i * 4));
2294 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2297 set_encodings(vs, (int32_t *)(data + 4), limit);
2298 break;
2299 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2300 if (len == 1)
2301 return 10;
2303 framebuffer_update_request(vs,
2304 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2305 read_u16(data, 6), read_u16(data, 8));
2306 break;
2307 case VNC_MSG_CLIENT_KEY_EVENT:
2308 if (len == 1)
2309 return 8;
2311 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2312 break;
2313 case VNC_MSG_CLIENT_POINTER_EVENT:
2314 if (len == 1)
2315 return 6;
2317 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2318 break;
2319 case VNC_MSG_CLIENT_CUT_TEXT:
2320 if (len == 1) {
2321 return 8;
2323 if (len == 8) {
2324 uint32_t dlen = read_u32(data, 4);
2325 if (dlen > (1 << 20)) {
2326 error_report("vnc: client_cut_text msg payload has %u bytes"
2327 " which exceeds our limit of 1MB.", dlen);
2328 vnc_client_error(vs);
2329 break;
2331 if (dlen > 0) {
2332 return 8 + dlen;
2336 client_cut_text(vs, read_u32(data, 4), data + 8);
2337 break;
2338 case VNC_MSG_CLIENT_QEMU:
2339 if (len == 1)
2340 return 2;
2342 switch (read_u8(data, 1)) {
2343 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2344 if (len == 2)
2345 return 12;
2347 ext_key_event(vs, read_u16(data, 2),
2348 read_u32(data, 4), read_u32(data, 8));
2349 break;
2350 case VNC_MSG_CLIENT_QEMU_AUDIO:
2351 if (len == 2)
2352 return 4;
2354 switch (read_u16 (data, 2)) {
2355 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2356 audio_add(vs);
2357 break;
2358 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2359 audio_del(vs);
2360 break;
2361 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2362 if (len == 4)
2363 return 10;
2364 switch (read_u8(data, 4)) {
2365 case 0: vs->as.fmt = AUD_FMT_U8; break;
2366 case 1: vs->as.fmt = AUD_FMT_S8; break;
2367 case 2: vs->as.fmt = AUD_FMT_U16; break;
2368 case 3: vs->as.fmt = AUD_FMT_S16; break;
2369 case 4: vs->as.fmt = AUD_FMT_U32; break;
2370 case 5: vs->as.fmt = AUD_FMT_S32; break;
2371 default:
2372 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2373 vnc_client_error(vs);
2374 break;
2376 vs->as.nchannels = read_u8(data, 5);
2377 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2378 VNC_DEBUG("Invalid audio channel coount %d\n",
2379 read_u8(data, 5));
2380 vnc_client_error(vs);
2381 break;
2383 vs->as.freq = read_u32(data, 6);
2384 break;
2385 default:
2386 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2387 vnc_client_error(vs);
2388 break;
2390 break;
2392 default:
2393 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2394 vnc_client_error(vs);
2395 break;
2397 break;
2398 default:
2399 VNC_DEBUG("Msg: %d\n", data[0]);
2400 vnc_client_error(vs);
2401 break;
2404 vnc_read_when(vs, protocol_client_msg, 1);
2405 return 0;
2408 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2410 char buf[1024];
2411 VncShareMode mode;
2412 int size;
2414 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2415 switch (vs->vd->share_policy) {
2416 case VNC_SHARE_POLICY_IGNORE:
2418 * Ignore the shared flag. Nothing to do here.
2420 * Doesn't conform to the rfb spec but is traditional qemu
2421 * behavior, thus left here as option for compatibility
2422 * reasons.
2424 break;
2425 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2427 * Policy: Allow clients ask for exclusive access.
2429 * Implementation: When a client asks for exclusive access,
2430 * disconnect all others. Shared connects are allowed as long
2431 * as no exclusive connection exists.
2433 * This is how the rfb spec suggests to handle the shared flag.
2435 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2436 VncState *client;
2437 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2438 if (vs == client) {
2439 continue;
2441 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2442 client->share_mode != VNC_SHARE_MODE_SHARED) {
2443 continue;
2445 vnc_disconnect_start(client);
2448 if (mode == VNC_SHARE_MODE_SHARED) {
2449 if (vs->vd->num_exclusive > 0) {
2450 vnc_disconnect_start(vs);
2451 return 0;
2454 break;
2455 case VNC_SHARE_POLICY_FORCE_SHARED:
2457 * Policy: Shared connects only.
2458 * Implementation: Disallow clients asking for exclusive access.
2460 * Useful for shared desktop sessions where you don't want
2461 * someone forgetting to say -shared when running the vnc
2462 * client disconnect everybody else.
2464 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2465 vnc_disconnect_start(vs);
2466 return 0;
2468 break;
2470 vnc_set_share_mode(vs, mode);
2472 if (vs->vd->num_shared > vs->vd->connections_limit) {
2473 vnc_disconnect_start(vs);
2474 return 0;
2477 vs->client_width = pixman_image_get_width(vs->vd->server);
2478 vs->client_height = pixman_image_get_height(vs->vd->server);
2479 vnc_write_u16(vs, vs->client_width);
2480 vnc_write_u16(vs, vs->client_height);
2482 pixel_format_message(vs);
2484 if (qemu_name)
2485 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2486 else
2487 size = snprintf(buf, sizeof(buf), "QEMU");
2489 vnc_write_u32(vs, size);
2490 vnc_write(vs, buf, size);
2491 vnc_flush(vs);
2493 vnc_client_cache_auth(vs);
2494 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2496 vnc_read_when(vs, protocol_client_msg, 1);
2498 return 0;
2501 void start_client_init(VncState *vs)
2503 vnc_read_when(vs, protocol_client_init, 1);
2506 static void make_challenge(VncState *vs)
2508 int i;
2510 srand(time(NULL)+getpid()+getpid()*987654+rand());
2512 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2513 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2516 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2518 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2519 size_t i, pwlen;
2520 unsigned char key[8];
2521 time_t now = time(NULL);
2522 QCryptoCipher *cipher = NULL;
2523 Error *err = NULL;
2525 if (!vs->vd->password) {
2526 VNC_DEBUG("No password configured on server");
2527 goto reject;
2529 if (vs->vd->expires < now) {
2530 VNC_DEBUG("Password is expired");
2531 goto reject;
2534 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2536 /* Calculate the expected challenge response */
2537 pwlen = strlen(vs->vd->password);
2538 for (i=0; i<sizeof(key); i++)
2539 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2541 cipher = qcrypto_cipher_new(
2542 QCRYPTO_CIPHER_ALG_DES_RFB,
2543 QCRYPTO_CIPHER_MODE_ECB,
2544 key, G_N_ELEMENTS(key),
2545 &err);
2546 if (!cipher) {
2547 VNC_DEBUG("Cannot initialize cipher %s",
2548 error_get_pretty(err));
2549 error_free(err);
2550 goto reject;
2553 if (qcrypto_cipher_encrypt(cipher,
2554 vs->challenge,
2555 response,
2556 VNC_AUTH_CHALLENGE_SIZE,
2557 &err) < 0) {
2558 VNC_DEBUG("Cannot encrypt challenge %s",
2559 error_get_pretty(err));
2560 error_free(err);
2561 goto reject;
2564 /* Compare expected vs actual challenge response */
2565 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2566 VNC_DEBUG("Client challenge response did not match\n");
2567 goto reject;
2568 } else {
2569 VNC_DEBUG("Accepting VNC challenge response\n");
2570 vnc_write_u32(vs, 0); /* Accept auth */
2571 vnc_flush(vs);
2573 start_client_init(vs);
2576 qcrypto_cipher_free(cipher);
2577 return 0;
2579 reject:
2580 vnc_write_u32(vs, 1); /* Reject auth */
2581 if (vs->minor >= 8) {
2582 static const char err[] = "Authentication failed";
2583 vnc_write_u32(vs, sizeof(err));
2584 vnc_write(vs, err, sizeof(err));
2586 vnc_flush(vs);
2587 vnc_client_error(vs);
2588 qcrypto_cipher_free(cipher);
2589 return 0;
2592 void start_auth_vnc(VncState *vs)
2594 make_challenge(vs);
2595 /* Send client a 'random' challenge */
2596 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2597 vnc_flush(vs);
2599 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2603 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2605 /* We only advertise 1 auth scheme at a time, so client
2606 * must pick the one we sent. Verify this */
2607 if (data[0] != vs->auth) { /* Reject auth */
2608 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2609 vnc_write_u32(vs, 1);
2610 if (vs->minor >= 8) {
2611 static const char err[] = "Authentication failed";
2612 vnc_write_u32(vs, sizeof(err));
2613 vnc_write(vs, err, sizeof(err));
2615 vnc_client_error(vs);
2616 } else { /* Accept requested auth */
2617 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2618 switch (vs->auth) {
2619 case VNC_AUTH_NONE:
2620 VNC_DEBUG("Accept auth none\n");
2621 if (vs->minor >= 8) {
2622 vnc_write_u32(vs, 0); /* Accept auth completion */
2623 vnc_flush(vs);
2625 start_client_init(vs);
2626 break;
2628 case VNC_AUTH_VNC:
2629 VNC_DEBUG("Start VNC auth\n");
2630 start_auth_vnc(vs);
2631 break;
2633 case VNC_AUTH_VENCRYPT:
2634 VNC_DEBUG("Accept VeNCrypt auth\n");
2635 start_auth_vencrypt(vs);
2636 break;
2638 #ifdef CONFIG_VNC_SASL
2639 case VNC_AUTH_SASL:
2640 VNC_DEBUG("Accept SASL auth\n");
2641 start_auth_sasl(vs);
2642 break;
2643 #endif /* CONFIG_VNC_SASL */
2645 default: /* Should not be possible, but just in case */
2646 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2647 vnc_write_u8(vs, 1);
2648 if (vs->minor >= 8) {
2649 static const char err[] = "Authentication failed";
2650 vnc_write_u32(vs, sizeof(err));
2651 vnc_write(vs, err, sizeof(err));
2653 vnc_client_error(vs);
2656 return 0;
2659 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2661 char local[13];
2663 memcpy(local, version, 12);
2664 local[12] = 0;
2666 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2667 VNC_DEBUG("Malformed protocol version %s\n", local);
2668 vnc_client_error(vs);
2669 return 0;
2671 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2672 if (vs->major != 3 ||
2673 (vs->minor != 3 &&
2674 vs->minor != 4 &&
2675 vs->minor != 5 &&
2676 vs->minor != 7 &&
2677 vs->minor != 8)) {
2678 VNC_DEBUG("Unsupported client version\n");
2679 vnc_write_u32(vs, VNC_AUTH_INVALID);
2680 vnc_flush(vs);
2681 vnc_client_error(vs);
2682 return 0;
2684 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2685 * as equivalent to v3.3 by servers
2687 if (vs->minor == 4 || vs->minor == 5)
2688 vs->minor = 3;
2690 if (vs->minor == 3) {
2691 if (vs->auth == VNC_AUTH_NONE) {
2692 VNC_DEBUG("Tell client auth none\n");
2693 vnc_write_u32(vs, vs->auth);
2694 vnc_flush(vs);
2695 start_client_init(vs);
2696 } else if (vs->auth == VNC_AUTH_VNC) {
2697 VNC_DEBUG("Tell client VNC auth\n");
2698 vnc_write_u32(vs, vs->auth);
2699 vnc_flush(vs);
2700 start_auth_vnc(vs);
2701 } else {
2702 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2703 vnc_write_u32(vs, VNC_AUTH_INVALID);
2704 vnc_flush(vs);
2705 vnc_client_error(vs);
2707 } else {
2708 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2709 vnc_write_u8(vs, 1); /* num auth */
2710 vnc_write_u8(vs, vs->auth);
2711 vnc_read_when(vs, protocol_client_auth, 1);
2712 vnc_flush(vs);
2715 return 0;
2718 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2720 struct VncSurface *vs = &vd->guest;
2722 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2725 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2727 int i, j;
2729 w = (x + w) / VNC_STAT_RECT;
2730 h = (y + h) / VNC_STAT_RECT;
2731 x /= VNC_STAT_RECT;
2732 y /= VNC_STAT_RECT;
2734 for (j = y; j <= h; j++) {
2735 for (i = x; i <= w; i++) {
2736 vs->lossy_rect[j][i] = 1;
2741 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2743 VncState *vs;
2744 int sty = y / VNC_STAT_RECT;
2745 int stx = x / VNC_STAT_RECT;
2746 int has_dirty = 0;
2748 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2749 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2751 QTAILQ_FOREACH(vs, &vd->clients, next) {
2752 int j;
2754 /* kernel send buffers are full -> refresh later */
2755 if (vs->output.offset) {
2756 continue;
2759 if (!vs->lossy_rect[sty][stx]) {
2760 continue;
2763 vs->lossy_rect[sty][stx] = 0;
2764 for (j = 0; j < VNC_STAT_RECT; ++j) {
2765 bitmap_set(vs->dirty[y + j],
2766 x / VNC_DIRTY_PIXELS_PER_BIT,
2767 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2769 has_dirty++;
2772 return has_dirty;
2775 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2777 int width = pixman_image_get_width(vd->guest.fb);
2778 int height = pixman_image_get_height(vd->guest.fb);
2779 int x, y;
2780 struct timeval res;
2781 int has_dirty = 0;
2783 for (y = 0; y < height; y += VNC_STAT_RECT) {
2784 for (x = 0; x < width; x += VNC_STAT_RECT) {
2785 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2787 rect->updated = false;
2791 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2793 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2794 return has_dirty;
2796 vd->guest.last_freq_check = *tv;
2798 for (y = 0; y < height; y += VNC_STAT_RECT) {
2799 for (x = 0; x < width; x += VNC_STAT_RECT) {
2800 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2801 int count = ARRAY_SIZE(rect->times);
2802 struct timeval min, max;
2804 if (!timerisset(&rect->times[count - 1])) {
2805 continue ;
2808 max = rect->times[(rect->idx + count - 1) % count];
2809 qemu_timersub(tv, &max, &res);
2811 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2812 rect->freq = 0;
2813 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2814 memset(rect->times, 0, sizeof (rect->times));
2815 continue ;
2818 min = rect->times[rect->idx];
2819 max = rect->times[(rect->idx + count - 1) % count];
2820 qemu_timersub(&max, &min, &res);
2822 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2823 rect->freq /= count;
2824 rect->freq = 1. / rect->freq;
2827 return has_dirty;
2830 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2832 int i, j;
2833 double total = 0;
2834 int num = 0;
2836 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2837 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2839 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2840 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2841 total += vnc_stat_rect(vs->vd, i, j)->freq;
2842 num++;
2846 if (num) {
2847 return total / num;
2848 } else {
2849 return 0;
2853 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2855 VncRectStat *rect;
2857 rect = vnc_stat_rect(vd, x, y);
2858 if (rect->updated) {
2859 return ;
2861 rect->times[rect->idx] = *tv;
2862 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2863 rect->updated = true;
2866 static int vnc_refresh_server_surface(VncDisplay *vd)
2868 int width = MIN(pixman_image_get_width(vd->guest.fb),
2869 pixman_image_get_width(vd->server));
2870 int height = MIN(pixman_image_get_height(vd->guest.fb),
2871 pixman_image_get_height(vd->server));
2872 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
2873 uint8_t *guest_row0 = NULL, *server_row0;
2874 VncState *vs;
2875 int has_dirty = 0;
2876 pixman_image_t *tmpbuf = NULL;
2878 struct timeval tv = { 0, 0 };
2880 if (!vd->non_adaptive) {
2881 gettimeofday(&tv, NULL);
2882 has_dirty = vnc_update_stats(vd, &tv);
2886 * Walk through the guest dirty map.
2887 * Check and copy modified bits from guest to server surface.
2888 * Update server dirty map.
2890 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2891 server_stride = guest_stride = guest_ll =
2892 pixman_image_get_stride(vd->server);
2893 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2894 server_stride);
2895 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2896 int width = pixman_image_get_width(vd->server);
2897 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2898 } else {
2899 int guest_bpp =
2900 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
2901 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2902 guest_stride = pixman_image_get_stride(vd->guest.fb);
2903 guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
2905 line_bytes = MIN(server_stride, guest_ll);
2907 for (;;) {
2908 int x;
2909 uint8_t *guest_ptr, *server_ptr;
2910 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2911 height * VNC_DIRTY_BPL(&vd->guest),
2912 y * VNC_DIRTY_BPL(&vd->guest));
2913 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2914 /* no more dirty bits */
2915 break;
2917 y = offset / VNC_DIRTY_BPL(&vd->guest);
2918 x = offset % VNC_DIRTY_BPL(&vd->guest);
2920 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2922 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2923 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2924 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2925 } else {
2926 guest_ptr = guest_row0 + y * guest_stride;
2928 guest_ptr += x * cmp_bytes;
2930 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2931 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2932 int _cmp_bytes = cmp_bytes;
2933 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2934 continue;
2936 if ((x + 1) * cmp_bytes > line_bytes) {
2937 _cmp_bytes = line_bytes - x * cmp_bytes;
2939 assert(_cmp_bytes >= 0);
2940 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2941 continue;
2943 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2944 if (!vd->non_adaptive) {
2945 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2946 y, &tv);
2948 QTAILQ_FOREACH(vs, &vd->clients, next) {
2949 set_bit(x, vs->dirty[y]);
2951 has_dirty++;
2954 y++;
2956 qemu_pixman_image_unref(tmpbuf);
2957 return has_dirty;
2960 static void vnc_refresh(DisplayChangeListener *dcl)
2962 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2963 VncState *vs, *vn;
2964 int has_dirty, rects = 0;
2966 if (QTAILQ_EMPTY(&vd->clients)) {
2967 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2968 return;
2971 graphic_hw_update(vd->dcl.con);
2973 if (vnc_trylock_display(vd)) {
2974 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2975 return;
2978 has_dirty = vnc_refresh_server_surface(vd);
2979 vnc_unlock_display(vd);
2981 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2982 rects += vnc_update_client(vs, has_dirty, false);
2983 /* vs might be free()ed here */
2986 if (has_dirty && rects) {
2987 vd->dcl.update_interval /= 2;
2988 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2989 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2991 } else {
2992 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2993 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2994 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2999 static void vnc_connect(VncDisplay *vd, int csock,
3000 bool skipauth, bool websocket)
3002 VncState *vs = g_malloc0(sizeof(VncState));
3003 int i;
3005 vs->csock = csock;
3006 vs->vd = vd;
3008 if (skipauth) {
3009 vs->auth = VNC_AUTH_NONE;
3010 vs->subauth = VNC_AUTH_INVALID;
3011 } else {
3012 if (websocket) {
3013 vs->auth = vd->ws_auth;
3014 vs->subauth = VNC_AUTH_INVALID;
3015 } else {
3016 vs->auth = vd->auth;
3017 vs->subauth = vd->subauth;
3020 VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
3021 csock, websocket, vs->auth, vs->subauth);
3023 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3024 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3025 vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));
3028 VNC_DEBUG("New client on socket %d\n", csock);
3029 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3030 qemu_set_nonblock(vs->csock);
3031 if (websocket) {
3032 vs->websocket = 1;
3033 if (vd->ws_tls) {
3034 qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io, NULL, vs);
3035 } else {
3036 qemu_set_fd_handler(vs->csock, vncws_handshake_read, NULL, vs);
3038 } else
3040 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
3043 vnc_client_cache_addr(vs);
3044 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3045 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3047 if (!vs->websocket) {
3048 vnc_init_state(vs);
3051 if (vd->num_connecting > vd->connections_limit) {
3052 QTAILQ_FOREACH(vs, &vd->clients, next) {
3053 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3054 vnc_disconnect_start(vs);
3055 return;
3061 void vnc_init_state(VncState *vs)
3063 vs->initialized = true;
3064 VncDisplay *vd = vs->vd;
3066 vs->last_x = -1;
3067 vs->last_y = -1;
3069 vs->as.freq = 44100;
3070 vs->as.nchannels = 2;
3071 vs->as.fmt = AUD_FMT_S16;
3072 vs->as.endianness = 0;
3074 qemu_mutex_init(&vs->output_mutex);
3075 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3077 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3079 graphic_hw_update(vd->dcl.con);
3081 vnc_write(vs, "RFB 003.008\n", 12);
3082 vnc_flush(vs);
3083 vnc_read_when(vs, protocol_version, 12);
3084 reset_keys(vs);
3085 if (vs->vd->lock_key_sync)
3086 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3088 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3089 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3091 /* vs might be free()ed here */
3094 static void vnc_listen_read(void *opaque, bool websocket)
3096 VncDisplay *vs = opaque;
3097 struct sockaddr_in addr;
3098 socklen_t addrlen = sizeof(addr);
3099 int csock;
3101 /* Catch-up */
3102 graphic_hw_update(vs->dcl.con);
3103 if (websocket) {
3104 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
3105 } else {
3106 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
3109 if (csock != -1) {
3110 socket_set_nodelay(csock);
3111 vnc_connect(vs, csock, false, websocket);
3115 static void vnc_listen_regular_read(void *opaque)
3117 vnc_listen_read(opaque, false);
3120 static void vnc_listen_websocket_read(void *opaque)
3122 vnc_listen_read(opaque, true);
3125 static const DisplayChangeListenerOps dcl_ops = {
3126 .dpy_name = "vnc",
3127 .dpy_refresh = vnc_refresh,
3128 .dpy_gfx_copy = vnc_dpy_copy,
3129 .dpy_gfx_update = vnc_dpy_update,
3130 .dpy_gfx_switch = vnc_dpy_switch,
3131 .dpy_gfx_check_format = qemu_pixman_check_format,
3132 .dpy_mouse_set = vnc_mouse_set,
3133 .dpy_cursor_define = vnc_dpy_cursor_define,
3136 void vnc_display_init(const char *id)
3138 VncDisplay *vs;
3140 if (vnc_display_find(id) != NULL) {
3141 return;
3143 vs = g_malloc0(sizeof(*vs));
3145 vs->id = strdup(id);
3146 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3148 vs->lsock = -1;
3149 vs->lwebsock = -1;
3151 QTAILQ_INIT(&vs->clients);
3152 vs->expires = TIME_MAX;
3154 if (keyboard_layout) {
3155 trace_vnc_key_map_init(keyboard_layout);
3156 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3157 } else {
3158 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3161 if (!vs->kbd_layout)
3162 exit(1);
3164 qemu_mutex_init(&vs->mutex);
3165 vnc_start_worker_thread();
3167 vs->dcl.ops = &dcl_ops;
3168 register_displaychangelistener(&vs->dcl);
3172 static void vnc_display_close(VncDisplay *vs)
3174 if (!vs)
3175 return;
3176 vs->enabled = false;
3177 vs->is_unix = false;
3178 if (vs->lsock != -1) {
3179 qemu_set_fd_handler(vs->lsock, NULL, NULL, NULL);
3180 close(vs->lsock);
3181 vs->lsock = -1;
3183 vs->ws_enabled = false;
3184 if (vs->lwebsock != -1) {
3185 qemu_set_fd_handler(vs->lwebsock, NULL, NULL, NULL);
3186 close(vs->lwebsock);
3187 vs->lwebsock = -1;
3189 vs->auth = VNC_AUTH_INVALID;
3190 vs->subauth = VNC_AUTH_INVALID;
3191 if (vs->tlscreds) {
3192 object_unparent(OBJECT(vs->tlscreds));
3194 g_free(vs->tlsaclname);
3195 vs->tlsaclname = NULL;
3198 int vnc_display_password(const char *id, const char *password)
3200 VncDisplay *vs = vnc_display_find(id);
3202 if (!vs) {
3203 return -EINVAL;
3205 if (vs->auth == VNC_AUTH_NONE) {
3206 error_printf_unless_qmp("If you want use passwords please enable "
3207 "password auth using '-vnc ${dpy},password'.");
3208 return -EINVAL;
3211 g_free(vs->password);
3212 vs->password = g_strdup(password);
3214 return 0;
3217 int vnc_display_pw_expire(const char *id, time_t expires)
3219 VncDisplay *vs = vnc_display_find(id);
3221 if (!vs) {
3222 return -EINVAL;
3225 vs->expires = expires;
3226 return 0;
3229 char *vnc_display_local_addr(const char *id)
3231 VncDisplay *vs = vnc_display_find(id);
3233 assert(vs);
3234 return vnc_socket_local_addr("%s:%s", vs->lsock);
3237 static QemuOptsList qemu_vnc_opts = {
3238 .name = "vnc",
3239 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3240 .implied_opt_name = "vnc",
3241 .desc = {
3243 .name = "vnc",
3244 .type = QEMU_OPT_STRING,
3246 .name = "websocket",
3247 .type = QEMU_OPT_STRING,
3249 .name = "tls-creds",
3250 .type = QEMU_OPT_STRING,
3252 /* Deprecated in favour of tls-creds */
3253 .name = "x509",
3254 .type = QEMU_OPT_STRING,
3256 .name = "share",
3257 .type = QEMU_OPT_STRING,
3259 .name = "display",
3260 .type = QEMU_OPT_STRING,
3262 .name = "head",
3263 .type = QEMU_OPT_NUMBER,
3265 .name = "connections",
3266 .type = QEMU_OPT_NUMBER,
3268 .name = "to",
3269 .type = QEMU_OPT_NUMBER,
3271 .name = "ipv4",
3272 .type = QEMU_OPT_BOOL,
3274 .name = "ipv6",
3275 .type = QEMU_OPT_BOOL,
3277 .name = "password",
3278 .type = QEMU_OPT_BOOL,
3280 .name = "reverse",
3281 .type = QEMU_OPT_BOOL,
3283 .name = "lock-key-sync",
3284 .type = QEMU_OPT_BOOL,
3286 .name = "sasl",
3287 .type = QEMU_OPT_BOOL,
3289 /* Deprecated in favour of tls-creds */
3290 .name = "tls",
3291 .type = QEMU_OPT_BOOL,
3293 /* Deprecated in favour of tls-creds */
3294 .name = "x509verify",
3295 .type = QEMU_OPT_STRING,
3297 .name = "acl",
3298 .type = QEMU_OPT_BOOL,
3300 .name = "lossy",
3301 .type = QEMU_OPT_BOOL,
3303 .name = "non-adaptive",
3304 .type = QEMU_OPT_BOOL,
3306 { /* end of list */ }
3311 static int
3312 vnc_display_setup_auth(VncDisplay *vs,
3313 bool password,
3314 bool sasl,
3315 bool websocket,
3316 Error **errp)
3319 * We have a choice of 3 authentication options
3321 * 1. none
3322 * 2. vnc
3323 * 3. sasl
3325 * The channel can be run in 2 modes
3327 * 1. clear
3328 * 2. tls
3330 * And TLS can use 2 types of credentials
3332 * 1. anon
3333 * 2. x509
3335 * We thus have 9 possible logical combinations
3337 * 1. clear + none
3338 * 2. clear + vnc
3339 * 3. clear + sasl
3340 * 4. tls + anon + none
3341 * 5. tls + anon + vnc
3342 * 6. tls + anon + sasl
3343 * 7. tls + x509 + none
3344 * 8. tls + x509 + vnc
3345 * 9. tls + x509 + sasl
3347 * These need to be mapped into the VNC auth schemes
3348 * in an appropriate manner. In regular VNC, all the
3349 * TLS options get mapped into VNC_AUTH_VENCRYPT
3350 * sub-auth types.
3352 * In websockets, the https:// protocol already provides
3353 * TLS support, so there is no need to make use of the
3354 * VeNCrypt extension. Furthermore, websockets browser
3355 * clients could not use VeNCrypt even if they wanted to,
3356 * as they cannot control when the TLS handshake takes
3357 * place. Thus there is no option but to rely on https://,
3358 * meaning combinations 4->6 and 7->9 will be mapped to
3359 * VNC auth schemes in the same way as combos 1->3.
3361 * Regardless of fact that we have a different mapping to
3362 * VNC auth mechs for plain VNC vs websockets VNC, the end
3363 * result has the same security characteristics.
3365 if (password) {
3366 if (vs->tlscreds) {
3367 vs->auth = VNC_AUTH_VENCRYPT;
3368 if (websocket) {
3369 vs->ws_tls = true;
3371 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3372 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3373 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3374 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3375 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3376 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3377 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3378 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3379 } else {
3380 error_setg(errp,
3381 "Unsupported TLS cred type %s",
3382 object_get_typename(OBJECT(vs->tlscreds)));
3383 return -1;
3385 } else {
3386 VNC_DEBUG("Initializing VNC server with password auth\n");
3387 vs->auth = VNC_AUTH_VNC;
3388 vs->subauth = VNC_AUTH_INVALID;
3390 if (websocket) {
3391 vs->ws_auth = VNC_AUTH_VNC;
3392 } else {
3393 vs->ws_auth = VNC_AUTH_INVALID;
3395 } else if (sasl) {
3396 if (vs->tlscreds) {
3397 vs->auth = VNC_AUTH_VENCRYPT;
3398 if (websocket) {
3399 vs->ws_tls = true;
3401 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3402 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3403 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3404 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3405 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3406 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3407 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3408 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3409 } else {
3410 error_setg(errp,
3411 "Unsupported TLS cred type %s",
3412 object_get_typename(OBJECT(vs->tlscreds)));
3413 return -1;
3415 } else {
3416 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3417 vs->auth = VNC_AUTH_SASL;
3418 vs->subauth = VNC_AUTH_INVALID;
3420 if (websocket) {
3421 vs->ws_auth = VNC_AUTH_SASL;
3422 } else {
3423 vs->ws_auth = VNC_AUTH_INVALID;
3425 } else {
3426 if (vs->tlscreds) {
3427 vs->auth = VNC_AUTH_VENCRYPT;
3428 if (websocket) {
3429 vs->ws_tls = true;
3431 if (object_dynamic_cast(OBJECT(vs->tlscreds),
3432 TYPE_QCRYPTO_TLS_CREDS_X509)) {
3433 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3434 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3435 } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
3436 TYPE_QCRYPTO_TLS_CREDS_ANON)) {
3437 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3438 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3439 } else {
3440 error_setg(errp,
3441 "Unsupported TLS cred type %s",
3442 object_get_typename(OBJECT(vs->tlscreds)));
3443 return -1;
3445 } else {
3446 VNC_DEBUG("Initializing VNC server with no auth\n");
3447 vs->auth = VNC_AUTH_NONE;
3448 vs->subauth = VNC_AUTH_INVALID;
3450 if (websocket) {
3451 vs->ws_auth = VNC_AUTH_NONE;
3452 } else {
3453 vs->ws_auth = VNC_AUTH_INVALID;
3456 return 0;
3461 * Handle back compat with old CLI syntax by creating some
3462 * suitable QCryptoTLSCreds objects
3464 static QCryptoTLSCreds *
3465 vnc_display_create_creds(bool x509,
3466 bool x509verify,
3467 const char *dir,
3468 const char *id,
3469 Error **errp)
3471 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3472 Object *parent = object_get_objects_root();
3473 Object *creds;
3474 Error *err = NULL;
3476 if (x509) {
3477 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3478 parent,
3479 credsid,
3480 &err,
3481 "endpoint", "server",
3482 "dir", dir,
3483 "verify-peer", x509verify ? "yes" : "no",
3484 NULL);
3485 } else {
3486 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3487 parent,
3488 credsid,
3489 &err,
3490 "endpoint", "server",
3491 NULL);
3494 g_free(credsid);
3496 if (err) {
3497 error_propagate(errp, err);
3498 return NULL;
3501 return QCRYPTO_TLS_CREDS(creds);
3505 void vnc_display_open(const char *id, Error **errp)
3507 VncDisplay *vs = vnc_display_find(id);
3508 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3509 QemuOpts *sopts, *wsopts;
3510 const char *share, *device_id;
3511 QemuConsole *con;
3512 bool password = false;
3513 bool reverse = false;
3514 const char *vnc;
3515 const char *has_to;
3516 char *h;
3517 bool has_ipv4 = false;
3518 bool has_ipv6 = false;
3519 const char *credid;
3520 const char *websocket;
3521 bool sasl = false;
3522 #ifdef CONFIG_VNC_SASL
3523 int saslErr;
3524 #endif
3525 int acl = 0;
3526 int lock_key_sync = 1;
3528 if (!vs) {
3529 error_setg(errp, "VNC display not active");
3530 return;
3532 vnc_display_close(vs);
3534 if (!opts) {
3535 return;
3537 vnc = qemu_opt_get(opts, "vnc");
3538 if (!vnc || strcmp(vnc, "none") == 0) {
3539 return;
3542 sopts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
3543 wsopts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
3545 h = strrchr(vnc, ':');
3546 if (h) {
3547 char *host;
3548 size_t hlen = h - vnc;
3550 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3551 host = g_strndup(vnc + 1, hlen - 2);
3552 } else {
3553 host = g_strndup(vnc, hlen);
3555 qemu_opt_set(sopts, "host", host, &error_abort);
3556 qemu_opt_set(wsopts, "host", host, &error_abort);
3557 qemu_opt_set(sopts, "port", h+1, &error_abort);
3558 g_free(host);
3559 } else {
3560 error_setg(errp, "no vnc port specified");
3561 goto fail;
3564 has_to = qemu_opt_get(opts, "to");
3565 has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3566 has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3567 if (has_to) {
3568 qemu_opt_set(sopts, "to", has_to, &error_abort);
3569 qemu_opt_set(wsopts, "to", has_to, &error_abort);
3571 if (has_ipv4) {
3572 qemu_opt_set(sopts, "ipv4", "on", &error_abort);
3573 qemu_opt_set(wsopts, "ipv4", "on", &error_abort);
3575 if (has_ipv6) {
3576 qemu_opt_set(sopts, "ipv6", "on", &error_abort);
3577 qemu_opt_set(wsopts, "ipv6", "on", &error_abort);
3580 password = qemu_opt_get_bool(opts, "password", false);
3581 if (password) {
3582 if (fips_get_state()) {
3583 error_setg(errp,
3584 "VNC password auth disabled due to FIPS mode, "
3585 "consider using the VeNCrypt or SASL authentication "
3586 "methods as an alternative");
3587 goto fail;
3589 if (!qcrypto_cipher_supports(
3590 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3591 error_setg(errp,
3592 "Cipher backend does not support DES RFB algorithm");
3593 goto fail;
3597 reverse = qemu_opt_get_bool(opts, "reverse", false);
3598 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3599 sasl = qemu_opt_get_bool(opts, "sasl", false);
3600 #ifndef CONFIG_VNC_SASL
3601 if (sasl) {
3602 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3603 goto fail;
3605 #endif /* CONFIG_VNC_SASL */
3606 credid = qemu_opt_get(opts, "tls-creds");
3607 if (credid) {
3608 Object *creds;
3609 if (qemu_opt_get(opts, "tls") ||
3610 qemu_opt_get(opts, "x509") ||
3611 qemu_opt_get(opts, "x509verify")) {
3612 error_setg(errp,
3613 "'credid' parameter is mutually exclusive with "
3614 "'tls', 'x509' and 'x509verify' parameters");
3615 goto fail;
3618 creds = object_resolve_path_component(
3619 object_get_objects_root(), credid);
3620 if (!creds) {
3621 error_setg(errp, "No TLS credentials with id '%s'",
3622 credid);
3623 goto fail;
3625 vs->tlscreds = (QCryptoTLSCreds *)
3626 object_dynamic_cast(creds,
3627 TYPE_QCRYPTO_TLS_CREDS);
3628 if (!vs->tlscreds) {
3629 error_setg(errp, "Object with id '%s' is not TLS credentials",
3630 credid);
3631 goto fail;
3633 object_ref(OBJECT(vs->tlscreds));
3635 if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3636 error_setg(errp,
3637 "Expecting TLS credentials with a server endpoint");
3638 goto fail;
3640 } else {
3641 const char *path;
3642 bool tls = false, x509 = false, x509verify = false;
3643 tls = qemu_opt_get_bool(opts, "tls", false);
3644 if (tls) {
3645 path = qemu_opt_get(opts, "x509");
3647 if (path) {
3648 x509 = true;
3649 } else {
3650 path = qemu_opt_get(opts, "x509verify");
3651 if (path) {
3652 x509 = true;
3653 x509verify = true;
3656 vs->tlscreds = vnc_display_create_creds(x509,
3657 x509verify,
3658 path,
3659 vs->id,
3660 errp);
3661 if (!vs->tlscreds) {
3662 goto fail;
3666 acl = qemu_opt_get_bool(opts, "acl", false);
3668 share = qemu_opt_get(opts, "share");
3669 if (share) {
3670 if (strcmp(share, "ignore") == 0) {
3671 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3672 } else if (strcmp(share, "allow-exclusive") == 0) {
3673 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3674 } else if (strcmp(share, "force-shared") == 0) {
3675 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3676 } else {
3677 error_setg(errp, "unknown vnc share= option");
3678 goto fail;
3680 } else {
3681 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3683 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3685 websocket = qemu_opt_get(opts, "websocket");
3686 if (websocket) {
3687 vs->ws_enabled = true;
3688 qemu_opt_set(wsopts, "port", websocket, &error_abort);
3689 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3690 error_setg(errp, "SHA1 hash support is required for websockets");
3691 goto fail;
3695 #ifdef CONFIG_VNC_JPEG
3696 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3697 #endif
3698 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3699 /* adaptive updates are only used with tight encoding and
3700 * if lossy updates are enabled so we can disable all the
3701 * calculations otherwise */
3702 if (!vs->lossy) {
3703 vs->non_adaptive = true;
3706 if (acl) {
3707 if (strcmp(vs->id, "default") == 0) {
3708 vs->tlsaclname = g_strdup("vnc.x509dname");
3709 } else {
3710 vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3712 qemu_acl_init(vs->tlsaclname);
3714 #ifdef CONFIG_VNC_SASL
3715 if (acl && sasl) {
3716 char *aclname;
3718 if (strcmp(vs->id, "default") == 0) {
3719 aclname = g_strdup("vnc.username");
3720 } else {
3721 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3723 vs->sasl.acl = qemu_acl_init(aclname);
3724 g_free(aclname);
3726 #endif
3728 if (vnc_display_setup_auth(vs, password, sasl, websocket, errp) < 0) {
3729 goto fail;
3732 #ifdef CONFIG_VNC_SASL
3733 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3734 error_setg(errp, "Failed to initialize SASL auth: %s",
3735 sasl_errstring(saslErr, NULL, NULL));
3736 goto fail;
3738 #endif
3739 vs->lock_key_sync = lock_key_sync;
3741 device_id = qemu_opt_get(opts, "display");
3742 if (device_id) {
3743 DeviceState *dev;
3744 int head = qemu_opt_get_number(opts, "head", 0);
3746 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3747 if (dev == NULL) {
3748 error_setg(errp, "Device '%s' not found", device_id);
3749 goto fail;
3752 con = qemu_console_lookup_by_device(dev, head);
3753 if (con == NULL) {
3754 error_setg(errp, "Device %s is not bound to a QemuConsole",
3755 device_id);
3756 goto fail;
3758 } else {
3759 con = NULL;
3762 if (con != vs->dcl.con) {
3763 unregister_displaychangelistener(&vs->dcl);
3764 vs->dcl.con = con;
3765 register_displaychangelistener(&vs->dcl);
3768 if (reverse) {
3769 /* connect to viewer */
3770 int csock;
3771 vs->lsock = -1;
3772 vs->lwebsock = -1;
3773 if (strncmp(vnc, "unix:", 5) == 0) {
3774 csock = unix_connect(vnc+5, errp);
3775 } else {
3776 csock = inet_connect(vnc, errp);
3778 if (csock < 0) {
3779 goto fail;
3781 vnc_connect(vs, csock, false, false);
3782 } else {
3783 /* listen for connects */
3784 if (strncmp(vnc, "unix:", 5) == 0) {
3785 vs->lsock = unix_listen(vnc+5, NULL, 0, errp);
3786 if (vs->lsock < 0) {
3787 goto fail;
3789 vs->is_unix = true;
3790 } else {
3791 vs->lsock = inet_listen_opts(sopts, 5900, errp);
3792 if (vs->lsock < 0) {
3793 goto fail;
3795 if (vs->ws_enabled) {
3796 vs->lwebsock = inet_listen_opts(wsopts, 0, errp);
3797 if (vs->lwebsock < 0) {
3798 if (vs->lsock != -1) {
3799 close(vs->lsock);
3800 vs->lsock = -1;
3802 goto fail;
3806 vs->enabled = true;
3807 qemu_set_fd_handler(vs->lsock, vnc_listen_regular_read, NULL, vs);
3808 if (vs->ws_enabled) {
3809 qemu_set_fd_handler(vs->lwebsock, vnc_listen_websocket_read,
3810 NULL, vs);
3813 qemu_opts_del(sopts);
3814 qemu_opts_del(wsopts);
3815 return;
3817 fail:
3818 qemu_opts_del(sopts);
3819 qemu_opts_del(wsopts);
3820 vs->enabled = false;
3821 vs->ws_enabled = false;
3824 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3826 VncDisplay *vs = vnc_display_find(id);
3828 if (!vs) {
3829 return;
3831 vnc_connect(vs, csock, skipauth, false);
3834 static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3836 int i = 2;
3837 char *id;
3839 id = g_strdup("default");
3840 while (qemu_opts_find(olist, id)) {
3841 g_free(id);
3842 id = g_strdup_printf("vnc%d", i++);
3844 qemu_opts_set_id(opts, id);
3847 QemuOpts *vnc_parse(const char *str, Error **errp)
3849 QemuOptsList *olist = qemu_find_opts("vnc");
3850 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
3851 const char *id;
3853 if (!opts) {
3854 return NULL;
3857 id = qemu_opts_id(opts);
3858 if (!id) {
3859 /* auto-assign id if not present */
3860 vnc_auto_assign_id(olist, opts);
3862 return opts;
3865 int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
3867 Error *local_err = NULL;
3868 char *id = (char *)qemu_opts_id(opts);
3870 assert(id);
3871 vnc_display_init(id);
3872 vnc_display_open(id, &local_err);
3873 if (local_err != NULL) {
3874 error_report("Failed to start VNC server: %s",
3875 error_get_pretty(local_err));
3876 error_free(local_err);
3877 exit(1);
3879 return 0;
3882 static void vnc_register_config(void)
3884 qemu_add_opts(&qemu_vnc_opts);
3886 machine_init(vnc_register_config);