numa: Rename set_numa_modes() to numa_post_machine_init()
[qemu/cris-port.git] / ui / vnc.c
blob02552ee27b26bde1812e1f9a0403f08baf06f45e
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/sockets.h"
33 #include "qemu/timer.h"
34 #include "qemu/acl.h"
35 #include "qemu/config-file.h"
36 #include "qapi/qmp/types.h"
37 #include "qmp-commands.h"
38 #include "qemu/osdep.h"
39 #include "ui/input.h"
40 #include "qapi-event.h"
42 #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
43 #define VNC_REFRESH_INTERVAL_INC 50
44 #define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
45 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
46 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
48 #include "vnc_keysym.h"
49 #include "d3des.h"
51 static QTAILQ_HEAD(, VncDisplay) vnc_displays =
52 QTAILQ_HEAD_INITIALIZER(vnc_displays);
54 static int vnc_cursor_define(VncState *vs);
55 static void vnc_release_modifiers(VncState *vs);
57 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
59 #ifdef _VNC_DEBUG
60 static const char *mn[] = {
61 [0] = "undefined",
62 [VNC_SHARE_MODE_CONNECTING] = "connecting",
63 [VNC_SHARE_MODE_SHARED] = "shared",
64 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
65 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
67 fprintf(stderr, "%s/%d: %s -> %s\n", __func__,
68 vs->csock, mn[vs->share_mode], mn[mode]);
69 #endif
71 switch (vs->share_mode) {
72 case VNC_SHARE_MODE_CONNECTING:
73 vs->vd->num_connecting--;
74 break;
75 case VNC_SHARE_MODE_SHARED:
76 vs->vd->num_shared--;
77 break;
78 case VNC_SHARE_MODE_EXCLUSIVE:
79 vs->vd->num_exclusive--;
80 break;
81 default:
82 break;
85 vs->share_mode = mode;
87 switch (vs->share_mode) {
88 case VNC_SHARE_MODE_CONNECTING:
89 vs->vd->num_connecting++;
90 break;
91 case VNC_SHARE_MODE_SHARED:
92 vs->vd->num_shared++;
93 break;
94 case VNC_SHARE_MODE_EXCLUSIVE:
95 vs->vd->num_exclusive++;
96 break;
97 default:
98 break;
102 static char *addr_to_string(const char *format,
103 struct sockaddr_storage *sa,
104 socklen_t salen) {
105 char *addr;
106 char host[NI_MAXHOST];
107 char serv[NI_MAXSERV];
108 int err;
109 size_t addrlen;
111 if ((err = getnameinfo((struct sockaddr *)sa, salen,
112 host, sizeof(host),
113 serv, sizeof(serv),
114 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
115 VNC_DEBUG("Cannot resolve address %d: %s\n",
116 err, gai_strerror(err));
117 return NULL;
120 /* Enough for the existing format + the 2 vars we're
121 * substituting in. */
122 addrlen = strlen(format) + strlen(host) + strlen(serv);
123 addr = g_malloc(addrlen + 1);
124 snprintf(addr, addrlen, format, host, serv);
125 addr[addrlen] = '\0';
127 return addr;
131 char *vnc_socket_local_addr(const char *format, int fd) {
132 struct sockaddr_storage sa;
133 socklen_t salen;
135 salen = sizeof(sa);
136 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
137 return NULL;
139 return addr_to_string(format, &sa, salen);
142 char *vnc_socket_remote_addr(const char *format, int fd) {
143 struct sockaddr_storage sa;
144 socklen_t salen;
146 salen = sizeof(sa);
147 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
148 return NULL;
150 return addr_to_string(format, &sa, salen);
153 static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
154 socklen_t salen)
156 VncBasicInfo *info;
157 char host[NI_MAXHOST];
158 char serv[NI_MAXSERV];
159 int err;
161 if ((err = getnameinfo((struct sockaddr *)sa, salen,
162 host, sizeof(host),
163 serv, sizeof(serv),
164 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
165 VNC_DEBUG("Cannot resolve address %d: %s\n",
166 err, gai_strerror(err));
167 return NULL;
170 info = g_malloc0(sizeof(VncBasicInfo));
171 info->host = g_strdup(host);
172 info->service = g_strdup(serv);
173 info->family = inet_netfamily(sa->ss_family);
174 return info;
177 static VncBasicInfo *vnc_basic_info_get_from_server_addr(int fd)
179 struct sockaddr_storage sa;
180 socklen_t salen;
182 salen = sizeof(sa);
183 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
184 return NULL;
187 return vnc_basic_info_get(&sa, salen);
190 static VncBasicInfo *vnc_basic_info_get_from_remote_addr(int fd)
192 struct sockaddr_storage sa;
193 socklen_t salen;
195 salen = sizeof(sa);
196 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
197 return NULL;
200 return vnc_basic_info_get(&sa, salen);
203 static const char *vnc_auth_name(VncDisplay *vd) {
204 switch (vd->auth) {
205 case VNC_AUTH_INVALID:
206 return "invalid";
207 case VNC_AUTH_NONE:
208 return "none";
209 case VNC_AUTH_VNC:
210 return "vnc";
211 case VNC_AUTH_RA2:
212 return "ra2";
213 case VNC_AUTH_RA2NE:
214 return "ra2ne";
215 case VNC_AUTH_TIGHT:
216 return "tight";
217 case VNC_AUTH_ULTRA:
218 return "ultra";
219 case VNC_AUTH_TLS:
220 return "tls";
221 case VNC_AUTH_VENCRYPT:
222 #ifdef CONFIG_VNC_TLS
223 switch (vd->subauth) {
224 case VNC_AUTH_VENCRYPT_PLAIN:
225 return "vencrypt+plain";
226 case VNC_AUTH_VENCRYPT_TLSNONE:
227 return "vencrypt+tls+none";
228 case VNC_AUTH_VENCRYPT_TLSVNC:
229 return "vencrypt+tls+vnc";
230 case VNC_AUTH_VENCRYPT_TLSPLAIN:
231 return "vencrypt+tls+plain";
232 case VNC_AUTH_VENCRYPT_X509NONE:
233 return "vencrypt+x509+none";
234 case VNC_AUTH_VENCRYPT_X509VNC:
235 return "vencrypt+x509+vnc";
236 case VNC_AUTH_VENCRYPT_X509PLAIN:
237 return "vencrypt+x509+plain";
238 case VNC_AUTH_VENCRYPT_TLSSASL:
239 return "vencrypt+tls+sasl";
240 case VNC_AUTH_VENCRYPT_X509SASL:
241 return "vencrypt+x509+sasl";
242 default:
243 return "vencrypt";
245 #else
246 return "vencrypt";
247 #endif
248 case VNC_AUTH_SASL:
249 return "sasl";
251 return "unknown";
254 static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
256 VncServerInfo *info;
257 VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vd->lsock);
258 if (!bi) {
259 return NULL;
262 info = g_malloc(sizeof(*info));
263 info->base = bi;
264 info->has_auth = true;
265 info->auth = g_strdup(vnc_auth_name(vd));
266 return info;
269 static void vnc_client_cache_auth(VncState *client)
271 if (!client->info) {
272 return;
275 #ifdef CONFIG_VNC_TLS
276 if (client->tls.session &&
277 client->tls.dname) {
278 client->info->has_x509_dname = true;
279 client->info->x509_dname = g_strdup(client->tls.dname);
281 #endif
282 #ifdef CONFIG_VNC_SASL
283 if (client->sasl.conn &&
284 client->sasl.username) {
285 client->info->has_sasl_username = true;
286 client->info->sasl_username = g_strdup(client->sasl.username);
288 #endif
291 static void vnc_client_cache_addr(VncState *client)
293 VncBasicInfo *bi = vnc_basic_info_get_from_remote_addr(client->csock);
295 if (bi) {
296 client->info = g_malloc0(sizeof(*client->info));
297 client->info->base = bi;
301 static void vnc_qmp_event(VncState *vs, QAPIEvent event)
303 VncServerInfo *si;
305 if (!vs->info) {
306 return;
308 g_assert(vs->info->base);
310 si = vnc_server_info_get(vs->vd);
311 if (!si) {
312 return;
315 switch (event) {
316 case QAPI_EVENT_VNC_CONNECTED:
317 qapi_event_send_vnc_connected(si, vs->info->base, &error_abort);
318 break;
319 case QAPI_EVENT_VNC_INITIALIZED:
320 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
321 break;
322 case QAPI_EVENT_VNC_DISCONNECTED:
323 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
324 break;
325 default:
326 break;
329 qapi_free_VncServerInfo(si);
332 static VncClientInfo *qmp_query_vnc_client(const VncState *client)
334 struct sockaddr_storage sa;
335 socklen_t salen = sizeof(sa);
336 char host[NI_MAXHOST];
337 char serv[NI_MAXSERV];
338 VncClientInfo *info;
340 if (getpeername(client->csock, (struct sockaddr *)&sa, &salen) < 0) {
341 return NULL;
344 if (getnameinfo((struct sockaddr *)&sa, salen,
345 host, sizeof(host),
346 serv, sizeof(serv),
347 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
348 return NULL;
351 info = g_malloc0(sizeof(*info));
352 info->base = g_malloc0(sizeof(*info->base));
353 info->base->host = g_strdup(host);
354 info->base->service = g_strdup(serv);
355 info->base->family = inet_netfamily(sa.ss_family);
356 #ifdef CONFIG_VNC_WS
357 info->base->websocket = client->websocket;
358 #endif
360 #ifdef CONFIG_VNC_TLS
361 if (client->tls.session && client->tls.dname) {
362 info->has_x509_dname = true;
363 info->x509_dname = g_strdup(client->tls.dname);
365 #endif
366 #ifdef CONFIG_VNC_SASL
367 if (client->sasl.conn && client->sasl.username) {
368 info->has_sasl_username = true;
369 info->sasl_username = g_strdup(client->sasl.username);
371 #endif
373 return info;
376 static VncDisplay *vnc_display_find(const char *id)
378 VncDisplay *vd;
380 if (id == NULL) {
381 return QTAILQ_FIRST(&vnc_displays);
383 QTAILQ_FOREACH(vd, &vnc_displays, next) {
384 if (strcmp(id, vd->id) == 0) {
385 return vd;
388 return NULL;
391 static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
393 VncClientInfoList *cinfo, *prev = NULL;
394 VncState *client;
396 QTAILQ_FOREACH(client, &vd->clients, next) {
397 cinfo = g_new0(VncClientInfoList, 1);
398 cinfo->value = qmp_query_vnc_client(client);
399 cinfo->next = prev;
400 prev = cinfo;
402 return prev;
405 VncInfo *qmp_query_vnc(Error **errp)
407 VncInfo *info = g_malloc0(sizeof(*info));
408 VncDisplay *vd = vnc_display_find(NULL);
410 if (vd == NULL || vd->display == NULL) {
411 info->enabled = false;
412 } else {
413 struct sockaddr_storage sa;
414 socklen_t salen = sizeof(sa);
415 char host[NI_MAXHOST];
416 char serv[NI_MAXSERV];
418 info->enabled = true;
420 /* for compatibility with the original command */
421 info->has_clients = true;
422 info->clients = qmp_query_client_list(vd);
424 if (vd->lsock == -1) {
425 return info;
428 if (getsockname(vd->lsock, (struct sockaddr *)&sa,
429 &salen) == -1) {
430 error_set(errp, QERR_UNDEFINED_ERROR);
431 goto out_error;
434 if (getnameinfo((struct sockaddr *)&sa, salen,
435 host, sizeof(host),
436 serv, sizeof(serv),
437 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
438 error_set(errp, QERR_UNDEFINED_ERROR);
439 goto out_error;
442 info->has_host = true;
443 info->host = g_strdup(host);
445 info->has_service = true;
446 info->service = g_strdup(serv);
448 info->has_family = true;
449 info->family = inet_netfamily(sa.ss_family);
451 info->has_auth = true;
452 info->auth = g_strdup(vnc_auth_name(vd));
455 return info;
457 out_error:
458 qapi_free_VncInfo(info);
459 return NULL;
462 static VncBasicInfoList *qmp_query_server_entry(int socket,
463 bool websocket,
464 VncBasicInfoList *prev)
466 VncBasicInfoList *list;
467 VncBasicInfo *info;
468 struct sockaddr_storage sa;
469 socklen_t salen = sizeof(sa);
470 char host[NI_MAXHOST];
471 char serv[NI_MAXSERV];
473 if (getsockname(socket, (struct sockaddr *)&sa, &salen) < 0 ||
474 getnameinfo((struct sockaddr *)&sa, salen,
475 host, sizeof(host), serv, sizeof(serv),
476 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
477 return prev;
480 info = g_new0(VncBasicInfo, 1);
481 info->host = g_strdup(host);
482 info->service = g_strdup(serv);
483 info->family = inet_netfamily(sa.ss_family);
484 info->websocket = websocket;
486 list = g_new0(VncBasicInfoList, 1);
487 list->value = info;
488 list->next = prev;
489 return list;
492 static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
494 switch (vd->auth) {
495 case VNC_AUTH_VNC:
496 info->auth = VNC_PRIMARY_AUTH_VNC;
497 break;
498 case VNC_AUTH_RA2:
499 info->auth = VNC_PRIMARY_AUTH_RA2;
500 break;
501 case VNC_AUTH_RA2NE:
502 info->auth = VNC_PRIMARY_AUTH_RA2NE;
503 break;
504 case VNC_AUTH_TIGHT:
505 info->auth = VNC_PRIMARY_AUTH_TIGHT;
506 break;
507 case VNC_AUTH_ULTRA:
508 info->auth = VNC_PRIMARY_AUTH_ULTRA;
509 break;
510 case VNC_AUTH_TLS:
511 info->auth = VNC_PRIMARY_AUTH_TLS;
512 break;
513 case VNC_AUTH_VENCRYPT:
514 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
515 #ifdef CONFIG_VNC_TLS
516 info->has_vencrypt = true;
517 switch (vd->subauth) {
518 case VNC_AUTH_VENCRYPT_PLAIN:
519 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
520 break;
521 case VNC_AUTH_VENCRYPT_TLSNONE:
522 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
523 break;
524 case VNC_AUTH_VENCRYPT_TLSVNC:
525 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
526 break;
527 case VNC_AUTH_VENCRYPT_TLSPLAIN:
528 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
529 break;
530 case VNC_AUTH_VENCRYPT_X509NONE:
531 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
532 break;
533 case VNC_AUTH_VENCRYPT_X509VNC:
534 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
535 break;
536 case VNC_AUTH_VENCRYPT_X509PLAIN:
537 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
538 break;
539 case VNC_AUTH_VENCRYPT_TLSSASL:
540 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
541 break;
542 case VNC_AUTH_VENCRYPT_X509SASL:
543 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
544 break;
545 default:
546 info->has_vencrypt = false;
547 break;
549 #endif
550 break;
551 case VNC_AUTH_SASL:
552 info->auth = VNC_PRIMARY_AUTH_SASL;
553 break;
554 case VNC_AUTH_NONE:
555 default:
556 info->auth = VNC_PRIMARY_AUTH_NONE;
557 break;
561 VncInfo2List *qmp_query_vnc_servers(Error **errp)
563 VncInfo2List *item, *prev = NULL;
564 VncInfo2 *info;
565 VncDisplay *vd;
566 DeviceState *dev;
568 QTAILQ_FOREACH(vd, &vnc_displays, next) {
569 info = g_new0(VncInfo2, 1);
570 info->id = g_strdup(vd->id);
571 info->clients = qmp_query_client_list(vd);
572 qmp_query_auth(vd, info);
573 if (vd->dcl.con) {
574 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
575 "device", NULL));
576 info->has_display = true;
577 info->display = g_strdup(dev->id);
579 if (vd->lsock != -1) {
580 info->server = qmp_query_server_entry(vd->lsock, false,
581 info->server);
583 #ifdef CONFIG_VNC_WS
584 if (vd->lwebsock != -1) {
585 info->server = qmp_query_server_entry(vd->lwebsock, true,
586 info->server);
588 #endif
590 item = g_new0(VncInfo2List, 1);
591 item->value = info;
592 item->next = prev;
593 prev = item;
595 return prev;
598 /* TODO
599 1) Get the queue working for IO.
600 2) there is some weirdness when using the -S option (the screen is grey
601 and not totally invalidated
602 3) resolutions > 1024
605 static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
606 static void vnc_disconnect_start(VncState *vs);
608 static void vnc_colordepth(VncState *vs);
609 static void framebuffer_update_request(VncState *vs, int incremental,
610 int x_position, int y_position,
611 int w, int h);
612 static void vnc_refresh(DisplayChangeListener *dcl);
613 static int vnc_refresh_server_surface(VncDisplay *vd);
615 static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
616 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
617 int width, int height,
618 int x, int y, int w, int h) {
619 /* this is needed this to ensure we updated all affected
620 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
621 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
622 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
624 x = MIN(x, width);
625 y = MIN(y, height);
626 w = MIN(x + w, width) - x;
627 h = MIN(y + h, height);
629 for (; y < h; y++) {
630 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
631 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
635 static void vnc_dpy_update(DisplayChangeListener *dcl,
636 int x, int y, int w, int h)
638 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
639 struct VncSurface *s = &vd->guest;
640 int width = pixman_image_get_width(vd->server);
641 int height = pixman_image_get_height(vd->server);
643 vnc_set_area_dirty(s->dirty, width, height, x, y, w, h);
646 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
647 int32_t encoding)
649 vnc_write_u16(vs, x);
650 vnc_write_u16(vs, y);
651 vnc_write_u16(vs, w);
652 vnc_write_u16(vs, h);
654 vnc_write_s32(vs, encoding);
657 void buffer_reserve(Buffer *buffer, size_t len)
659 if ((buffer->capacity - buffer->offset) < len) {
660 buffer->capacity += (len + 1024);
661 buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
665 static int buffer_empty(Buffer *buffer)
667 return buffer->offset == 0;
670 uint8_t *buffer_end(Buffer *buffer)
672 return buffer->buffer + buffer->offset;
675 void buffer_reset(Buffer *buffer)
677 buffer->offset = 0;
680 void buffer_free(Buffer *buffer)
682 g_free(buffer->buffer);
683 buffer->offset = 0;
684 buffer->capacity = 0;
685 buffer->buffer = NULL;
688 void buffer_append(Buffer *buffer, const void *data, size_t len)
690 memcpy(buffer->buffer + buffer->offset, data, len);
691 buffer->offset += len;
694 void buffer_advance(Buffer *buf, size_t len)
696 memmove(buf->buffer, buf->buffer + len,
697 (buf->offset - len));
698 buf->offset -= len;
701 static void vnc_desktop_resize(VncState *vs)
703 if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
704 return;
706 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
707 vs->client_height == pixman_image_get_height(vs->vd->server)) {
708 return;
710 vs->client_width = pixman_image_get_width(vs->vd->server);
711 vs->client_height = pixman_image_get_height(vs->vd->server);
712 vnc_lock_output(vs);
713 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
714 vnc_write_u8(vs, 0);
715 vnc_write_u16(vs, 1); /* number of rects */
716 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
717 VNC_ENCODING_DESKTOPRESIZE);
718 vnc_unlock_output(vs);
719 vnc_flush(vs);
722 static void vnc_abort_display_jobs(VncDisplay *vd)
724 VncState *vs;
726 QTAILQ_FOREACH(vs, &vd->clients, next) {
727 vnc_lock_output(vs);
728 vs->abort = true;
729 vnc_unlock_output(vs);
731 QTAILQ_FOREACH(vs, &vd->clients, next) {
732 vnc_jobs_join(vs);
734 QTAILQ_FOREACH(vs, &vd->clients, next) {
735 vnc_lock_output(vs);
736 vs->abort = false;
737 vnc_unlock_output(vs);
741 int vnc_server_fb_stride(VncDisplay *vd)
743 return pixman_image_get_stride(vd->server);
746 void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
748 uint8_t *ptr;
750 ptr = (uint8_t *)pixman_image_get_data(vd->server);
751 ptr += y * vnc_server_fb_stride(vd);
752 ptr += x * VNC_SERVER_FB_BYTES;
753 return ptr;
756 static void vnc_dpy_switch(DisplayChangeListener *dcl,
757 DisplaySurface *surface)
759 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
760 VncState *vs;
761 int width, height;
763 vnc_abort_display_jobs(vd);
765 /* server surface */
766 qemu_pixman_image_unref(vd->server);
767 vd->ds = surface;
768 width = MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
769 VNC_DIRTY_PIXELS_PER_BIT));
770 height = MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
771 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
772 width, height, NULL, 0);
774 /* guest surface */
775 #if 0 /* FIXME */
776 if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
777 console_color_init(ds);
778 #endif
779 qemu_pixman_image_unref(vd->guest.fb);
780 vd->guest.fb = pixman_image_ref(surface->image);
781 vd->guest.format = surface->format;
782 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
783 vnc_set_area_dirty(vd->guest.dirty, width, height, 0, 0,
784 width, height);
786 QTAILQ_FOREACH(vs, &vd->clients, next) {
787 vnc_colordepth(vs);
788 vnc_desktop_resize(vs);
789 if (vs->vd->cursor) {
790 vnc_cursor_define(vs);
792 memset(vs->dirty, 0x00, sizeof(vs->dirty));
793 vnc_set_area_dirty(vs->dirty, width, height, 0, 0,
794 width, height);
798 /* fastest code */
799 static void vnc_write_pixels_copy(VncState *vs,
800 void *pixels, int size)
802 vnc_write(vs, pixels, size);
805 /* slowest but generic code. */
806 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
808 uint8_t r, g, b;
810 #if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
811 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
812 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
813 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
814 #else
815 # error need some bits here if you change VNC_SERVER_FB_FORMAT
816 #endif
817 v = (r << vs->client_pf.rshift) |
818 (g << vs->client_pf.gshift) |
819 (b << vs->client_pf.bshift);
820 switch (vs->client_pf.bytes_per_pixel) {
821 case 1:
822 buf[0] = v;
823 break;
824 case 2:
825 if (vs->client_be) {
826 buf[0] = v >> 8;
827 buf[1] = v;
828 } else {
829 buf[1] = v >> 8;
830 buf[0] = v;
832 break;
833 default:
834 case 4:
835 if (vs->client_be) {
836 buf[0] = v >> 24;
837 buf[1] = v >> 16;
838 buf[2] = v >> 8;
839 buf[3] = v;
840 } else {
841 buf[3] = v >> 24;
842 buf[2] = v >> 16;
843 buf[1] = v >> 8;
844 buf[0] = v;
846 break;
850 static void vnc_write_pixels_generic(VncState *vs,
851 void *pixels1, int size)
853 uint8_t buf[4];
855 if (VNC_SERVER_FB_BYTES == 4) {
856 uint32_t *pixels = pixels1;
857 int n, i;
858 n = size >> 2;
859 for (i = 0; i < n; i++) {
860 vnc_convert_pixel(vs, buf, pixels[i]);
861 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
866 int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
868 int i;
869 uint8_t *row;
870 VncDisplay *vd = vs->vd;
872 row = vnc_server_fb_ptr(vd, x, y);
873 for (i = 0; i < h; i++) {
874 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
875 row += vnc_server_fb_stride(vd);
877 return 1;
880 int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
882 int n = 0;
884 switch(vs->vnc_encoding) {
885 case VNC_ENCODING_ZLIB:
886 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
887 break;
888 case VNC_ENCODING_HEXTILE:
889 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
890 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
891 break;
892 case VNC_ENCODING_TIGHT:
893 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
894 break;
895 case VNC_ENCODING_TIGHT_PNG:
896 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
897 break;
898 case VNC_ENCODING_ZRLE:
899 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
900 break;
901 case VNC_ENCODING_ZYWRLE:
902 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
903 break;
904 default:
905 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
906 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
907 break;
909 return n;
912 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
914 /* send bitblit op to the vnc client */
915 vnc_lock_output(vs);
916 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
917 vnc_write_u8(vs, 0);
918 vnc_write_u16(vs, 1); /* number of rects */
919 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
920 vnc_write_u16(vs, src_x);
921 vnc_write_u16(vs, src_y);
922 vnc_unlock_output(vs);
923 vnc_flush(vs);
926 static void vnc_dpy_copy(DisplayChangeListener *dcl,
927 int src_x, int src_y,
928 int dst_x, int dst_y, int w, int h)
930 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
931 VncState *vs, *vn;
932 uint8_t *src_row;
933 uint8_t *dst_row;
934 int i, x, y, pitch, inc, w_lim, s;
935 int cmp_bytes;
937 vnc_refresh_server_surface(vd);
938 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
939 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
940 vs->force_update = 1;
941 vnc_update_client(vs, 1, true);
942 /* vs might be free()ed here */
946 /* do bitblit op on the local surface too */
947 pitch = vnc_server_fb_stride(vd);
948 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
949 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
950 y = dst_y;
951 inc = 1;
952 if (dst_y > src_y) {
953 /* copy backwards */
954 src_row += pitch * (h-1);
955 dst_row += pitch * (h-1);
956 pitch = -pitch;
957 y = dst_y + h - 1;
958 inc = -1;
960 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
961 if (w_lim < 0) {
962 w_lim = w;
963 } else {
964 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
966 for (i = 0; i < h; i++) {
967 for (x = 0; x <= w_lim;
968 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
969 if (x == w_lim) {
970 if ((s = w - w_lim) == 0)
971 break;
972 } else if (!x) {
973 s = (VNC_DIRTY_PIXELS_PER_BIT -
974 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
975 s = MIN(s, w_lim);
976 } else {
977 s = VNC_DIRTY_PIXELS_PER_BIT;
979 cmp_bytes = s * VNC_SERVER_FB_BYTES;
980 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
981 continue;
982 memmove(dst_row, src_row, cmp_bytes);
983 QTAILQ_FOREACH(vs, &vd->clients, next) {
984 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
985 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
986 vs->dirty[y]);
990 src_row += pitch - w * VNC_SERVER_FB_BYTES;
991 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
992 y += inc;
995 QTAILQ_FOREACH(vs, &vd->clients, next) {
996 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
997 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
1002 static void vnc_mouse_set(DisplayChangeListener *dcl,
1003 int x, int y, int visible)
1005 /* can we ask the client(s) to move the pointer ??? */
1008 static int vnc_cursor_define(VncState *vs)
1010 QEMUCursor *c = vs->vd->cursor;
1011 int isize;
1013 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
1014 vnc_lock_output(vs);
1015 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1016 vnc_write_u8(vs, 0); /* padding */
1017 vnc_write_u16(vs, 1); /* # of rects */
1018 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1019 VNC_ENCODING_RICH_CURSOR);
1020 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
1021 vnc_write_pixels_generic(vs, c->data, isize);
1022 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
1023 vnc_unlock_output(vs);
1024 return 0;
1026 return -1;
1029 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1030 QEMUCursor *c)
1032 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1033 VncState *vs;
1035 cursor_put(vd->cursor);
1036 g_free(vd->cursor_mask);
1038 vd->cursor = c;
1039 cursor_get(vd->cursor);
1040 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1041 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1042 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1044 QTAILQ_FOREACH(vs, &vd->clients, next) {
1045 vnc_cursor_define(vs);
1049 static int find_and_clear_dirty_height(struct VncState *vs,
1050 int y, int last_x, int x, int height)
1052 int h;
1054 for (h = 1; h < (height - y); h++) {
1055 if (!test_bit(last_x, vs->dirty[y + h])) {
1056 break;
1058 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1061 return h;
1064 static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
1066 vs->has_dirty += has_dirty;
1067 if (vs->need_update && vs->csock != -1) {
1068 VncDisplay *vd = vs->vd;
1069 VncJob *job;
1070 int y;
1071 int height, width;
1072 int n = 0;
1074 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
1075 /* kernel send buffers are full -> drop frames to throttle */
1076 return 0;
1078 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
1079 return 0;
1082 * Send screen updates to the vnc client using the server
1083 * surface and server dirty map. guest surface updates
1084 * happening in parallel don't disturb us, the next pass will
1085 * send them to the client.
1087 job = vnc_job_new(vs);
1089 height = pixman_image_get_height(vd->server);
1090 width = pixman_image_get_width(vd->server);
1092 y = 0;
1093 for (;;) {
1094 int x, h;
1095 unsigned long x2;
1096 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1097 height * VNC_DIRTY_BPL(vs),
1098 y * VNC_DIRTY_BPL(vs));
1099 if (offset == height * VNC_DIRTY_BPL(vs)) {
1100 /* no more dirty bits */
1101 break;
1103 y = offset / VNC_DIRTY_BPL(vs);
1104 x = offset % VNC_DIRTY_BPL(vs);
1105 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1106 VNC_DIRTY_BPL(vs), x);
1107 bitmap_clear(vs->dirty[y], x, x2 - x);
1108 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1109 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1110 if (x2 > x) {
1111 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1112 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1116 vnc_job_push(job);
1117 if (sync) {
1118 vnc_jobs_join(vs);
1120 vs->force_update = 0;
1121 vs->has_dirty = 0;
1122 return n;
1125 if (vs->csock == -1) {
1126 vnc_disconnect_finish(vs);
1127 } else if (sync) {
1128 vnc_jobs_join(vs);
1131 return 0;
1134 /* audio */
1135 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1137 VncState *vs = opaque;
1139 switch (cmd) {
1140 case AUD_CNOTIFY_DISABLE:
1141 vnc_lock_output(vs);
1142 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1143 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1144 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1145 vnc_unlock_output(vs);
1146 vnc_flush(vs);
1147 break;
1149 case AUD_CNOTIFY_ENABLE:
1150 vnc_lock_output(vs);
1151 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1152 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1153 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1154 vnc_unlock_output(vs);
1155 vnc_flush(vs);
1156 break;
1160 static void audio_capture_destroy(void *opaque)
1164 static void audio_capture(void *opaque, void *buf, int size)
1166 VncState *vs = opaque;
1168 vnc_lock_output(vs);
1169 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1170 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1171 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1172 vnc_write_u32(vs, size);
1173 vnc_write(vs, buf, size);
1174 vnc_unlock_output(vs);
1175 vnc_flush(vs);
1178 static void audio_add(VncState *vs)
1180 struct audio_capture_ops ops;
1182 if (vs->audio_cap) {
1183 error_report("audio already running");
1184 return;
1187 ops.notify = audio_capture_notify;
1188 ops.destroy = audio_capture_destroy;
1189 ops.capture = audio_capture;
1191 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1192 if (!vs->audio_cap) {
1193 error_report("Failed to add audio capture");
1197 static void audio_del(VncState *vs)
1199 if (vs->audio_cap) {
1200 AUD_del_capture(vs->audio_cap, vs);
1201 vs->audio_cap = NULL;
1205 static void vnc_disconnect_start(VncState *vs)
1207 if (vs->csock == -1)
1208 return;
1209 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1210 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
1211 closesocket(vs->csock);
1212 vs->csock = -1;
1215 void vnc_disconnect_finish(VncState *vs)
1217 int i;
1219 vnc_jobs_join(vs); /* Wait encoding jobs */
1221 vnc_lock_output(vs);
1222 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1224 buffer_free(&vs->input);
1225 buffer_free(&vs->output);
1226 #ifdef CONFIG_VNC_WS
1227 buffer_free(&vs->ws_input);
1228 buffer_free(&vs->ws_output);
1229 #endif /* CONFIG_VNC_WS */
1231 qapi_free_VncClientInfo(vs->info);
1233 vnc_zlib_clear(vs);
1234 vnc_tight_clear(vs);
1235 vnc_zrle_clear(vs);
1237 #ifdef CONFIG_VNC_TLS
1238 vnc_tls_client_cleanup(vs);
1239 #endif /* CONFIG_VNC_TLS */
1240 #ifdef CONFIG_VNC_SASL
1241 vnc_sasl_client_cleanup(vs);
1242 #endif /* CONFIG_VNC_SASL */
1243 audio_del(vs);
1244 vnc_release_modifiers(vs);
1246 if (vs->initialized) {
1247 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1248 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1251 if (vs->vd->lock_key_sync)
1252 qemu_remove_led_event_handler(vs->led);
1253 vnc_unlock_output(vs);
1255 qemu_mutex_destroy(&vs->output_mutex);
1256 if (vs->bh != NULL) {
1257 qemu_bh_delete(vs->bh);
1259 buffer_free(&vs->jobs_buffer);
1261 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1262 g_free(vs->lossy_rect[i]);
1264 g_free(vs->lossy_rect);
1265 g_free(vs);
1268 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
1270 if (ret == 0 || ret == -1) {
1271 if (ret == -1) {
1272 switch (last_errno) {
1273 case EINTR:
1274 case EAGAIN:
1275 #ifdef _WIN32
1276 case WSAEWOULDBLOCK:
1277 #endif
1278 return 0;
1279 default:
1280 break;
1284 VNC_DEBUG("Closing down client sock: ret %d, errno %d\n",
1285 ret, ret < 0 ? last_errno : 0);
1286 vnc_disconnect_start(vs);
1288 return 0;
1290 return ret;
1294 void vnc_client_error(VncState *vs)
1296 VNC_DEBUG("Closing down client sock: protocol error\n");
1297 vnc_disconnect_start(vs);
1300 #ifdef CONFIG_VNC_TLS
1301 static long vnc_client_write_tls(gnutls_session_t *session,
1302 const uint8_t *data,
1303 size_t datalen)
1305 long ret = gnutls_write(*session, data, datalen);
1306 if (ret < 0) {
1307 if (ret == GNUTLS_E_AGAIN) {
1308 errno = EAGAIN;
1309 } else {
1310 errno = EIO;
1312 ret = -1;
1314 return ret;
1316 #endif /* CONFIG_VNC_TLS */
1319 * Called to write a chunk of data to the client socket. The data may
1320 * be the raw data, or may have already been encoded by SASL.
1321 * The data will be written either straight onto the socket, or
1322 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1324 * NB, it is theoretically possible to have 2 layers of encryption,
1325 * both SASL, and this TLS layer. It is highly unlikely in practice
1326 * though, since SASL encryption will typically be a no-op if TLS
1327 * is active
1329 * Returns the number of bytes written, which may be less than
1330 * the requested 'datalen' if the socket would block. Returns
1331 * -1 on error, and disconnects the client socket.
1333 long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1335 long ret;
1336 #ifdef CONFIG_VNC_TLS
1337 if (vs->tls.session) {
1338 ret = vnc_client_write_tls(&vs->tls.session, data, datalen);
1339 } else {
1340 #ifdef CONFIG_VNC_WS
1341 if (vs->ws_tls.session) {
1342 ret = vnc_client_write_tls(&vs->ws_tls.session, data, datalen);
1343 } else
1344 #endif /* CONFIG_VNC_WS */
1345 #endif /* CONFIG_VNC_TLS */
1347 ret = send(vs->csock, (const void *)data, datalen, 0);
1349 #ifdef CONFIG_VNC_TLS
1351 #endif /* CONFIG_VNC_TLS */
1352 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1353 return vnc_client_io_error(vs, ret, socket_error());
1358 * Called to write buffered data to the client socket, when not
1359 * using any SASL SSF encryption layers. Will write as much data
1360 * as possible without blocking. If all buffered data is written,
1361 * will switch the FD poll() handler back to read monitoring.
1363 * Returns the number of bytes written, which may be less than
1364 * the buffered output data if the socket would block. Returns
1365 * -1 on error, and disconnects the client socket.
1367 static long vnc_client_write_plain(VncState *vs)
1369 long ret;
1371 #ifdef CONFIG_VNC_SASL
1372 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1373 vs->output.buffer, vs->output.capacity, vs->output.offset,
1374 vs->sasl.waitWriteSSF);
1376 if (vs->sasl.conn &&
1377 vs->sasl.runSSF &&
1378 vs->sasl.waitWriteSSF) {
1379 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1380 if (ret)
1381 vs->sasl.waitWriteSSF -= ret;
1382 } else
1383 #endif /* CONFIG_VNC_SASL */
1384 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1385 if (!ret)
1386 return 0;
1388 buffer_advance(&vs->output, ret);
1390 if (vs->output.offset == 0) {
1391 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1394 return ret;
1399 * First function called whenever there is data to be written to
1400 * the client socket. Will delegate actual work according to whether
1401 * SASL SSF layers are enabled (thus requiring encryption calls)
1403 static void vnc_client_write_locked(void *opaque)
1405 VncState *vs = opaque;
1407 #ifdef CONFIG_VNC_SASL
1408 if (vs->sasl.conn &&
1409 vs->sasl.runSSF &&
1410 !vs->sasl.waitWriteSSF) {
1411 vnc_client_write_sasl(vs);
1412 } else
1413 #endif /* CONFIG_VNC_SASL */
1415 #ifdef CONFIG_VNC_WS
1416 if (vs->encode_ws) {
1417 vnc_client_write_ws(vs);
1418 } else
1419 #endif /* CONFIG_VNC_WS */
1421 vnc_client_write_plain(vs);
1426 void vnc_client_write(void *opaque)
1428 VncState *vs = opaque;
1430 vnc_lock_output(vs);
1431 if (vs->output.offset
1432 #ifdef CONFIG_VNC_WS
1433 || vs->ws_output.offset
1434 #endif
1436 vnc_client_write_locked(opaque);
1437 } else if (vs->csock != -1) {
1438 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1440 vnc_unlock_output(vs);
1443 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1445 vs->read_handler = func;
1446 vs->read_handler_expect = expecting;
1449 #ifdef CONFIG_VNC_TLS
1450 static long vnc_client_read_tls(gnutls_session_t *session, uint8_t *data,
1451 size_t datalen)
1453 long ret = gnutls_read(*session, data, datalen);
1454 if (ret < 0) {
1455 if (ret == GNUTLS_E_AGAIN) {
1456 errno = EAGAIN;
1457 } else {
1458 errno = EIO;
1460 ret = -1;
1462 return ret;
1464 #endif /* CONFIG_VNC_TLS */
1467 * Called to read a chunk of data from the client socket. The data may
1468 * be the raw data, or may need to be further decoded by SASL.
1469 * The data will be read either straight from to the socket, or
1470 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1472 * NB, it is theoretically possible to have 2 layers of encryption,
1473 * both SASL, and this TLS layer. It is highly unlikely in practice
1474 * though, since SASL encryption will typically be a no-op if TLS
1475 * is active
1477 * Returns the number of bytes read, which may be less than
1478 * the requested 'datalen' if the socket would block. Returns
1479 * -1 on error, and disconnects the client socket.
1481 long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1483 long ret;
1484 #ifdef CONFIG_VNC_TLS
1485 if (vs->tls.session) {
1486 ret = vnc_client_read_tls(&vs->tls.session, data, datalen);
1487 } else {
1488 #ifdef CONFIG_VNC_WS
1489 if (vs->ws_tls.session) {
1490 ret = vnc_client_read_tls(&vs->ws_tls.session, data, datalen);
1491 } else
1492 #endif /* CONFIG_VNC_WS */
1493 #endif /* CONFIG_VNC_TLS */
1495 ret = qemu_recv(vs->csock, data, datalen, 0);
1497 #ifdef CONFIG_VNC_TLS
1499 #endif /* CONFIG_VNC_TLS */
1500 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1501 return vnc_client_io_error(vs, ret, socket_error());
1506 * Called to read data from the client socket to the input buffer,
1507 * when not using any SASL SSF encryption layers. Will read as much
1508 * data as possible without blocking.
1510 * Returns the number of bytes read. Returns -1 on error, and
1511 * disconnects the client socket.
1513 static long vnc_client_read_plain(VncState *vs)
1515 int ret;
1516 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1517 vs->input.buffer, vs->input.capacity, vs->input.offset);
1518 buffer_reserve(&vs->input, 4096);
1519 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1520 if (!ret)
1521 return 0;
1522 vs->input.offset += ret;
1523 return ret;
1526 static void vnc_jobs_bh(void *opaque)
1528 VncState *vs = opaque;
1530 vnc_jobs_consume_buffer(vs);
1534 * First function called whenever there is more data to be read from
1535 * the client socket. Will delegate actual work according to whether
1536 * SASL SSF layers are enabled (thus requiring decryption calls)
1538 void vnc_client_read(void *opaque)
1540 VncState *vs = opaque;
1541 long ret;
1543 #ifdef CONFIG_VNC_SASL
1544 if (vs->sasl.conn && vs->sasl.runSSF)
1545 ret = vnc_client_read_sasl(vs);
1546 else
1547 #endif /* CONFIG_VNC_SASL */
1548 #ifdef CONFIG_VNC_WS
1549 if (vs->encode_ws) {
1550 ret = vnc_client_read_ws(vs);
1551 if (ret == -1) {
1552 vnc_disconnect_start(vs);
1553 return;
1554 } else if (ret == -2) {
1555 vnc_client_error(vs);
1556 return;
1558 } else
1559 #endif /* CONFIG_VNC_WS */
1561 ret = vnc_client_read_plain(vs);
1563 if (!ret) {
1564 if (vs->csock == -1)
1565 vnc_disconnect_finish(vs);
1566 return;
1569 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1570 size_t len = vs->read_handler_expect;
1571 int ret;
1573 ret = vs->read_handler(vs, vs->input.buffer, len);
1574 if (vs->csock == -1) {
1575 vnc_disconnect_finish(vs);
1576 return;
1579 if (!ret) {
1580 buffer_advance(&vs->input, len);
1581 } else {
1582 vs->read_handler_expect = ret;
1587 void vnc_write(VncState *vs, const void *data, size_t len)
1589 buffer_reserve(&vs->output, len);
1591 if (vs->csock != -1 && buffer_empty(&vs->output)) {
1592 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1595 buffer_append(&vs->output, data, len);
1598 void vnc_write_s32(VncState *vs, int32_t value)
1600 vnc_write_u32(vs, *(uint32_t *)&value);
1603 void vnc_write_u32(VncState *vs, uint32_t value)
1605 uint8_t buf[4];
1607 buf[0] = (value >> 24) & 0xFF;
1608 buf[1] = (value >> 16) & 0xFF;
1609 buf[2] = (value >> 8) & 0xFF;
1610 buf[3] = value & 0xFF;
1612 vnc_write(vs, buf, 4);
1615 void vnc_write_u16(VncState *vs, uint16_t value)
1617 uint8_t buf[2];
1619 buf[0] = (value >> 8) & 0xFF;
1620 buf[1] = value & 0xFF;
1622 vnc_write(vs, buf, 2);
1625 void vnc_write_u8(VncState *vs, uint8_t value)
1627 vnc_write(vs, (char *)&value, 1);
1630 void vnc_flush(VncState *vs)
1632 vnc_lock_output(vs);
1633 if (vs->csock != -1 && (vs->output.offset
1634 #ifdef CONFIG_VNC_WS
1635 || vs->ws_output.offset
1636 #endif
1637 )) {
1638 vnc_client_write_locked(vs);
1640 vnc_unlock_output(vs);
1643 static uint8_t read_u8(uint8_t *data, size_t offset)
1645 return data[offset];
1648 static uint16_t read_u16(uint8_t *data, size_t offset)
1650 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1653 static int32_t read_s32(uint8_t *data, size_t offset)
1655 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1656 (data[offset + 2] << 8) | data[offset + 3]);
1659 uint32_t read_u32(uint8_t *data, size_t offset)
1661 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1662 (data[offset + 2] << 8) | data[offset + 3]);
1665 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1669 static void check_pointer_type_change(Notifier *notifier, void *data)
1671 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1672 int absolute = qemu_input_is_absolute();
1674 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1675 vnc_lock_output(vs);
1676 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1677 vnc_write_u8(vs, 0);
1678 vnc_write_u16(vs, 1);
1679 vnc_framebuffer_update(vs, absolute, 0,
1680 pixman_image_get_width(vs->vd->server),
1681 pixman_image_get_height(vs->vd->server),
1682 VNC_ENCODING_POINTER_TYPE_CHANGE);
1683 vnc_unlock_output(vs);
1684 vnc_flush(vs);
1686 vs->absolute = absolute;
1689 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1691 static uint32_t bmap[INPUT_BUTTON_MAX] = {
1692 [INPUT_BUTTON_LEFT] = 0x01,
1693 [INPUT_BUTTON_MIDDLE] = 0x02,
1694 [INPUT_BUTTON_RIGHT] = 0x04,
1695 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1696 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1698 QemuConsole *con = vs->vd->dcl.con;
1699 int width = pixman_image_get_width(vs->vd->server);
1700 int height = pixman_image_get_height(vs->vd->server);
1702 if (vs->last_bmask != button_mask) {
1703 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1704 vs->last_bmask = button_mask;
1707 if (vs->absolute) {
1708 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1709 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1710 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1711 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1712 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1713 } else {
1714 if (vs->last_x != -1) {
1715 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1716 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1718 vs->last_x = x;
1719 vs->last_y = y;
1721 qemu_input_event_sync();
1724 static void reset_keys(VncState *vs)
1726 int i;
1727 for(i = 0; i < 256; i++) {
1728 if (vs->modifiers_state[i]) {
1729 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1730 vs->modifiers_state[i] = 0;
1735 static void press_key(VncState *vs, int keysym)
1737 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1738 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1739 qemu_input_event_send_key_delay(0);
1740 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1741 qemu_input_event_send_key_delay(0);
1744 static int current_led_state(VncState *vs)
1746 int ledstate = 0;
1748 if (vs->modifiers_state[0x46]) {
1749 ledstate |= QEMU_SCROLL_LOCK_LED;
1751 if (vs->modifiers_state[0x45]) {
1752 ledstate |= QEMU_NUM_LOCK_LED;
1754 if (vs->modifiers_state[0x3a]) {
1755 ledstate |= QEMU_CAPS_LOCK_LED;
1758 return ledstate;
1761 static void vnc_led_state_change(VncState *vs)
1763 int ledstate = 0;
1765 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1766 return;
1769 ledstate = current_led_state(vs);
1770 vnc_lock_output(vs);
1771 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1772 vnc_write_u8(vs, 0);
1773 vnc_write_u16(vs, 1);
1774 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1775 vnc_write_u8(vs, ledstate);
1776 vnc_unlock_output(vs);
1777 vnc_flush(vs);
1780 static void kbd_leds(void *opaque, int ledstate)
1782 VncState *vs = opaque;
1783 int caps, num, scr;
1784 bool has_changed = (ledstate != current_led_state(vs));
1786 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1787 (ledstate & QEMU_NUM_LOCK_LED),
1788 (ledstate & QEMU_SCROLL_LOCK_LED));
1790 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1791 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1792 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1794 if (vs->modifiers_state[0x3a] != caps) {
1795 vs->modifiers_state[0x3a] = caps;
1797 if (vs->modifiers_state[0x45] != num) {
1798 vs->modifiers_state[0x45] = num;
1800 if (vs->modifiers_state[0x46] != scr) {
1801 vs->modifiers_state[0x46] = scr;
1804 /* Sending the current led state message to the client */
1805 if (has_changed) {
1806 vnc_led_state_change(vs);
1810 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1812 /* QEMU console switch */
1813 switch(keycode) {
1814 case 0x2a: /* Left Shift */
1815 case 0x36: /* Right Shift */
1816 case 0x1d: /* Left CTRL */
1817 case 0x9d: /* Right CTRL */
1818 case 0x38: /* Left ALT */
1819 case 0xb8: /* Right ALT */
1820 if (down)
1821 vs->modifiers_state[keycode] = 1;
1822 else
1823 vs->modifiers_state[keycode] = 0;
1824 break;
1825 case 0x02 ... 0x0a: /* '1' to '9' keys */
1826 if (vs->vd->dcl.con == NULL &&
1827 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1828 /* Reset the modifiers sent to the current console */
1829 reset_keys(vs);
1830 console_select(keycode - 0x02);
1831 return;
1833 break;
1834 case 0x3a: /* CapsLock */
1835 case 0x45: /* NumLock */
1836 if (down)
1837 vs->modifiers_state[keycode] ^= 1;
1838 break;
1841 /* Turn off the lock state sync logic if the client support the led
1842 state extension.
1844 if (down && vs->vd->lock_key_sync &&
1845 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1846 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1847 /* If the numlock state needs to change then simulate an additional
1848 keypress before sending this one. This will happen if the user
1849 toggles numlock away from the VNC window.
1851 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1852 if (!vs->modifiers_state[0x45]) {
1853 trace_vnc_key_sync_numlock(true);
1854 vs->modifiers_state[0x45] = 1;
1855 press_key(vs, 0xff7f);
1857 } else {
1858 if (vs->modifiers_state[0x45]) {
1859 trace_vnc_key_sync_numlock(false);
1860 vs->modifiers_state[0x45] = 0;
1861 press_key(vs, 0xff7f);
1866 if (down && vs->vd->lock_key_sync &&
1867 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1868 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1869 /* If the capslock state needs to change then simulate an additional
1870 keypress before sending this one. This will happen if the user
1871 toggles capslock away from the VNC window.
1873 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1874 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1875 int capslock = !!(vs->modifiers_state[0x3a]);
1876 if (capslock) {
1877 if (uppercase == shift) {
1878 trace_vnc_key_sync_capslock(false);
1879 vs->modifiers_state[0x3a] = 0;
1880 press_key(vs, 0xffe5);
1882 } else {
1883 if (uppercase != shift) {
1884 trace_vnc_key_sync_capslock(true);
1885 vs->modifiers_state[0x3a] = 1;
1886 press_key(vs, 0xffe5);
1891 if (qemu_console_is_graphic(NULL)) {
1892 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1893 } else {
1894 bool numlock = vs->modifiers_state[0x45];
1895 bool control = (vs->modifiers_state[0x1d] ||
1896 vs->modifiers_state[0x9d]);
1897 /* QEMU console emulation */
1898 if (down) {
1899 switch (keycode) {
1900 case 0x2a: /* Left Shift */
1901 case 0x36: /* Right Shift */
1902 case 0x1d: /* Left CTRL */
1903 case 0x9d: /* Right CTRL */
1904 case 0x38: /* Left ALT */
1905 case 0xb8: /* Right ALT */
1906 break;
1907 case 0xc8:
1908 kbd_put_keysym(QEMU_KEY_UP);
1909 break;
1910 case 0xd0:
1911 kbd_put_keysym(QEMU_KEY_DOWN);
1912 break;
1913 case 0xcb:
1914 kbd_put_keysym(QEMU_KEY_LEFT);
1915 break;
1916 case 0xcd:
1917 kbd_put_keysym(QEMU_KEY_RIGHT);
1918 break;
1919 case 0xd3:
1920 kbd_put_keysym(QEMU_KEY_DELETE);
1921 break;
1922 case 0xc7:
1923 kbd_put_keysym(QEMU_KEY_HOME);
1924 break;
1925 case 0xcf:
1926 kbd_put_keysym(QEMU_KEY_END);
1927 break;
1928 case 0xc9:
1929 kbd_put_keysym(QEMU_KEY_PAGEUP);
1930 break;
1931 case 0xd1:
1932 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1933 break;
1935 case 0x47:
1936 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1937 break;
1938 case 0x48:
1939 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1940 break;
1941 case 0x49:
1942 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1943 break;
1944 case 0x4b:
1945 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1946 break;
1947 case 0x4c:
1948 kbd_put_keysym('5');
1949 break;
1950 case 0x4d:
1951 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1952 break;
1953 case 0x4f:
1954 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1955 break;
1956 case 0x50:
1957 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1958 break;
1959 case 0x51:
1960 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1961 break;
1962 case 0x52:
1963 kbd_put_keysym('0');
1964 break;
1965 case 0x53:
1966 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1967 break;
1969 case 0xb5:
1970 kbd_put_keysym('/');
1971 break;
1972 case 0x37:
1973 kbd_put_keysym('*');
1974 break;
1975 case 0x4a:
1976 kbd_put_keysym('-');
1977 break;
1978 case 0x4e:
1979 kbd_put_keysym('+');
1980 break;
1981 case 0x9c:
1982 kbd_put_keysym('\n');
1983 break;
1985 default:
1986 if (control) {
1987 kbd_put_keysym(sym & 0x1f);
1988 } else {
1989 kbd_put_keysym(sym);
1991 break;
1997 static void vnc_release_modifiers(VncState *vs)
1999 static const int keycodes[] = {
2000 /* shift, control, alt keys, both left & right */
2001 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
2003 int i, keycode;
2005 if (!qemu_console_is_graphic(NULL)) {
2006 return;
2008 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
2009 keycode = keycodes[i];
2010 if (!vs->modifiers_state[keycode]) {
2011 continue;
2013 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
2017 static const char *code2name(int keycode)
2019 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
2022 static void key_event(VncState *vs, int down, uint32_t sym)
2024 int keycode;
2025 int lsym = sym;
2027 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2028 lsym = lsym - 'A' + 'a';
2031 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
2032 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2033 do_key_event(vs, down, keycode, sym);
2036 static void ext_key_event(VncState *vs, int down,
2037 uint32_t sym, uint16_t keycode)
2039 /* if the user specifies a keyboard layout, always use it */
2040 if (keyboard_layout) {
2041 key_event(vs, down, sym);
2042 } else {
2043 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2044 do_key_event(vs, down, keycode, sym);
2048 static void framebuffer_update_request(VncState *vs, int incremental,
2049 int x, int y, int w, int h)
2051 int width = pixman_image_get_width(vs->vd->server);
2052 int height = pixman_image_get_height(vs->vd->server);
2054 vs->need_update = 1;
2056 if (incremental) {
2057 return;
2060 vs->force_update = 1;
2061 vnc_set_area_dirty(vs->dirty, width, height, x, y, w, h);
2064 static void send_ext_key_event_ack(VncState *vs)
2066 vnc_lock_output(vs);
2067 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2068 vnc_write_u8(vs, 0);
2069 vnc_write_u16(vs, 1);
2070 vnc_framebuffer_update(vs, 0, 0,
2071 pixman_image_get_width(vs->vd->server),
2072 pixman_image_get_height(vs->vd->server),
2073 VNC_ENCODING_EXT_KEY_EVENT);
2074 vnc_unlock_output(vs);
2075 vnc_flush(vs);
2078 static void send_ext_audio_ack(VncState *vs)
2080 vnc_lock_output(vs);
2081 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2082 vnc_write_u8(vs, 0);
2083 vnc_write_u16(vs, 1);
2084 vnc_framebuffer_update(vs, 0, 0,
2085 pixman_image_get_width(vs->vd->server),
2086 pixman_image_get_height(vs->vd->server),
2087 VNC_ENCODING_AUDIO);
2088 vnc_unlock_output(vs);
2089 vnc_flush(vs);
2092 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2094 int i;
2095 unsigned int enc = 0;
2097 vs->features = 0;
2098 vs->vnc_encoding = 0;
2099 vs->tight.compression = 9;
2100 vs->tight.quality = -1; /* Lossless by default */
2101 vs->absolute = -1;
2104 * Start from the end because the encodings are sent in order of preference.
2105 * This way the preferred encoding (first encoding defined in the array)
2106 * will be set at the end of the loop.
2108 for (i = n_encodings - 1; i >= 0; i--) {
2109 enc = encodings[i];
2110 switch (enc) {
2111 case VNC_ENCODING_RAW:
2112 vs->vnc_encoding = enc;
2113 break;
2114 case VNC_ENCODING_COPYRECT:
2115 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2116 break;
2117 case VNC_ENCODING_HEXTILE:
2118 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2119 vs->vnc_encoding = enc;
2120 break;
2121 case VNC_ENCODING_TIGHT:
2122 vs->features |= VNC_FEATURE_TIGHT_MASK;
2123 vs->vnc_encoding = enc;
2124 break;
2125 #ifdef CONFIG_VNC_PNG
2126 case VNC_ENCODING_TIGHT_PNG:
2127 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2128 vs->vnc_encoding = enc;
2129 break;
2130 #endif
2131 case VNC_ENCODING_ZLIB:
2132 vs->features |= VNC_FEATURE_ZLIB_MASK;
2133 vs->vnc_encoding = enc;
2134 break;
2135 case VNC_ENCODING_ZRLE:
2136 vs->features |= VNC_FEATURE_ZRLE_MASK;
2137 vs->vnc_encoding = enc;
2138 break;
2139 case VNC_ENCODING_ZYWRLE:
2140 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2141 vs->vnc_encoding = enc;
2142 break;
2143 case VNC_ENCODING_DESKTOPRESIZE:
2144 vs->features |= VNC_FEATURE_RESIZE_MASK;
2145 break;
2146 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2147 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2148 break;
2149 case VNC_ENCODING_RICH_CURSOR:
2150 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2151 break;
2152 case VNC_ENCODING_EXT_KEY_EVENT:
2153 send_ext_key_event_ack(vs);
2154 break;
2155 case VNC_ENCODING_AUDIO:
2156 send_ext_audio_ack(vs);
2157 break;
2158 case VNC_ENCODING_WMVi:
2159 vs->features |= VNC_FEATURE_WMVI_MASK;
2160 break;
2161 case VNC_ENCODING_LED_STATE:
2162 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2163 break;
2164 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2165 vs->tight.compression = (enc & 0x0F);
2166 break;
2167 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2168 if (vs->vd->lossy) {
2169 vs->tight.quality = (enc & 0x0F);
2171 break;
2172 default:
2173 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2174 break;
2177 vnc_desktop_resize(vs);
2178 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2179 vnc_led_state_change(vs);
2182 static void set_pixel_conversion(VncState *vs)
2184 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2186 if (fmt == VNC_SERVER_FB_FORMAT) {
2187 vs->write_pixels = vnc_write_pixels_copy;
2188 vnc_hextile_set_pixel_conversion(vs, 0);
2189 } else {
2190 vs->write_pixels = vnc_write_pixels_generic;
2191 vnc_hextile_set_pixel_conversion(vs, 1);
2195 static void set_pixel_format(VncState *vs,
2196 int bits_per_pixel, int depth,
2197 int big_endian_flag, int true_color_flag,
2198 int red_max, int green_max, int blue_max,
2199 int red_shift, int green_shift, int blue_shift)
2201 if (!true_color_flag) {
2202 vnc_client_error(vs);
2203 return;
2206 switch (bits_per_pixel) {
2207 case 8:
2208 case 16:
2209 case 32:
2210 break;
2211 default:
2212 vnc_client_error(vs);
2213 return;
2216 vs->client_pf.rmax = red_max;
2217 vs->client_pf.rbits = hweight_long(red_max);
2218 vs->client_pf.rshift = red_shift;
2219 vs->client_pf.rmask = red_max << red_shift;
2220 vs->client_pf.gmax = green_max;
2221 vs->client_pf.gbits = hweight_long(green_max);
2222 vs->client_pf.gshift = green_shift;
2223 vs->client_pf.gmask = green_max << green_shift;
2224 vs->client_pf.bmax = blue_max;
2225 vs->client_pf.bbits = hweight_long(blue_max);
2226 vs->client_pf.bshift = blue_shift;
2227 vs->client_pf.bmask = blue_max << blue_shift;
2228 vs->client_pf.bits_per_pixel = bits_per_pixel;
2229 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2230 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2231 vs->client_be = big_endian_flag;
2233 set_pixel_conversion(vs);
2235 graphic_hw_invalidate(vs->vd->dcl.con);
2236 graphic_hw_update(vs->vd->dcl.con);
2239 static void pixel_format_message (VncState *vs) {
2240 char pad[3] = { 0, 0, 0 };
2242 vs->client_pf = qemu_default_pixelformat(32);
2244 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2245 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2247 #ifdef HOST_WORDS_BIGENDIAN
2248 vnc_write_u8(vs, 1); /* big-endian-flag */
2249 #else
2250 vnc_write_u8(vs, 0); /* big-endian-flag */
2251 #endif
2252 vnc_write_u8(vs, 1); /* true-color-flag */
2253 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2254 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2255 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2256 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2257 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2258 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2259 vnc_write(vs, pad, 3); /* padding */
2261 vnc_hextile_set_pixel_conversion(vs, 0);
2262 vs->write_pixels = vnc_write_pixels_copy;
2265 static void vnc_colordepth(VncState *vs)
2267 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2268 /* Sending a WMVi message to notify the client*/
2269 vnc_lock_output(vs);
2270 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2271 vnc_write_u8(vs, 0);
2272 vnc_write_u16(vs, 1); /* number of rects */
2273 vnc_framebuffer_update(vs, 0, 0,
2274 pixman_image_get_width(vs->vd->server),
2275 pixman_image_get_height(vs->vd->server),
2276 VNC_ENCODING_WMVi);
2277 pixel_format_message(vs);
2278 vnc_unlock_output(vs);
2279 vnc_flush(vs);
2280 } else {
2281 set_pixel_conversion(vs);
2285 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2287 int i;
2288 uint16_t limit;
2289 VncDisplay *vd = vs->vd;
2291 if (data[0] > 3) {
2292 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2295 switch (data[0]) {
2296 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2297 if (len == 1)
2298 return 20;
2300 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2301 read_u8(data, 6), read_u8(data, 7),
2302 read_u16(data, 8), read_u16(data, 10),
2303 read_u16(data, 12), read_u8(data, 14),
2304 read_u8(data, 15), read_u8(data, 16));
2305 break;
2306 case VNC_MSG_CLIENT_SET_ENCODINGS:
2307 if (len == 1)
2308 return 4;
2310 if (len == 4) {
2311 limit = read_u16(data, 2);
2312 if (limit > 0)
2313 return 4 + (limit * 4);
2314 } else
2315 limit = read_u16(data, 2);
2317 for (i = 0; i < limit; i++) {
2318 int32_t val = read_s32(data, 4 + (i * 4));
2319 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2322 set_encodings(vs, (int32_t *)(data + 4), limit);
2323 break;
2324 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2325 if (len == 1)
2326 return 10;
2328 framebuffer_update_request(vs,
2329 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2330 read_u16(data, 6), read_u16(data, 8));
2331 break;
2332 case VNC_MSG_CLIENT_KEY_EVENT:
2333 if (len == 1)
2334 return 8;
2336 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2337 break;
2338 case VNC_MSG_CLIENT_POINTER_EVENT:
2339 if (len == 1)
2340 return 6;
2342 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2343 break;
2344 case VNC_MSG_CLIENT_CUT_TEXT:
2345 if (len == 1) {
2346 return 8;
2348 if (len == 8) {
2349 uint32_t dlen = read_u32(data, 4);
2350 if (dlen > (1 << 20)) {
2351 error_report("vnc: client_cut_text msg payload has %u bytes"
2352 " which exceeds our limit of 1MB.", dlen);
2353 vnc_client_error(vs);
2354 break;
2356 if (dlen > 0) {
2357 return 8 + dlen;
2361 client_cut_text(vs, read_u32(data, 4), data + 8);
2362 break;
2363 case VNC_MSG_CLIENT_QEMU:
2364 if (len == 1)
2365 return 2;
2367 switch (read_u8(data, 1)) {
2368 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2369 if (len == 2)
2370 return 12;
2372 ext_key_event(vs, read_u16(data, 2),
2373 read_u32(data, 4), read_u32(data, 8));
2374 break;
2375 case VNC_MSG_CLIENT_QEMU_AUDIO:
2376 if (len == 2)
2377 return 4;
2379 switch (read_u16 (data, 2)) {
2380 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2381 audio_add(vs);
2382 break;
2383 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2384 audio_del(vs);
2385 break;
2386 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2387 if (len == 4)
2388 return 10;
2389 switch (read_u8(data, 4)) {
2390 case 0: vs->as.fmt = AUD_FMT_U8; break;
2391 case 1: vs->as.fmt = AUD_FMT_S8; break;
2392 case 2: vs->as.fmt = AUD_FMT_U16; break;
2393 case 3: vs->as.fmt = AUD_FMT_S16; break;
2394 case 4: vs->as.fmt = AUD_FMT_U32; break;
2395 case 5: vs->as.fmt = AUD_FMT_S32; break;
2396 default:
2397 printf("Invalid audio format %d\n", read_u8(data, 4));
2398 vnc_client_error(vs);
2399 break;
2401 vs->as.nchannels = read_u8(data, 5);
2402 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2403 printf("Invalid audio channel coount %d\n",
2404 read_u8(data, 5));
2405 vnc_client_error(vs);
2406 break;
2408 vs->as.freq = read_u32(data, 6);
2409 break;
2410 default:
2411 printf ("Invalid audio message %d\n", read_u8(data, 4));
2412 vnc_client_error(vs);
2413 break;
2415 break;
2417 default:
2418 printf("Msg: %d\n", read_u16(data, 0));
2419 vnc_client_error(vs);
2420 break;
2422 break;
2423 default:
2424 printf("Msg: %d\n", data[0]);
2425 vnc_client_error(vs);
2426 break;
2429 vnc_read_when(vs, protocol_client_msg, 1);
2430 return 0;
2433 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2435 char buf[1024];
2436 VncShareMode mode;
2437 int size;
2439 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2440 switch (vs->vd->share_policy) {
2441 case VNC_SHARE_POLICY_IGNORE:
2443 * Ignore the shared flag. Nothing to do here.
2445 * Doesn't conform to the rfb spec but is traditional qemu
2446 * behavior, thus left here as option for compatibility
2447 * reasons.
2449 break;
2450 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2452 * Policy: Allow clients ask for exclusive access.
2454 * Implementation: When a client asks for exclusive access,
2455 * disconnect all others. Shared connects are allowed as long
2456 * as no exclusive connection exists.
2458 * This is how the rfb spec suggests to handle the shared flag.
2460 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2461 VncState *client;
2462 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2463 if (vs == client) {
2464 continue;
2466 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2467 client->share_mode != VNC_SHARE_MODE_SHARED) {
2468 continue;
2470 vnc_disconnect_start(client);
2473 if (mode == VNC_SHARE_MODE_SHARED) {
2474 if (vs->vd->num_exclusive > 0) {
2475 vnc_disconnect_start(vs);
2476 return 0;
2479 break;
2480 case VNC_SHARE_POLICY_FORCE_SHARED:
2482 * Policy: Shared connects only.
2483 * Implementation: Disallow clients asking for exclusive access.
2485 * Useful for shared desktop sessions where you don't want
2486 * someone forgetting to say -shared when running the vnc
2487 * client disconnect everybody else.
2489 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2490 vnc_disconnect_start(vs);
2491 return 0;
2493 break;
2495 vnc_set_share_mode(vs, mode);
2497 if (vs->vd->num_shared > vs->vd->connections_limit) {
2498 vnc_disconnect_start(vs);
2499 return 0;
2502 vs->client_width = pixman_image_get_width(vs->vd->server);
2503 vs->client_height = pixman_image_get_height(vs->vd->server);
2504 vnc_write_u16(vs, vs->client_width);
2505 vnc_write_u16(vs, vs->client_height);
2507 pixel_format_message(vs);
2509 if (qemu_name)
2510 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2511 else
2512 size = snprintf(buf, sizeof(buf), "QEMU");
2514 vnc_write_u32(vs, size);
2515 vnc_write(vs, buf, size);
2516 vnc_flush(vs);
2518 vnc_client_cache_auth(vs);
2519 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2521 vnc_read_when(vs, protocol_client_msg, 1);
2523 return 0;
2526 void start_client_init(VncState *vs)
2528 vnc_read_when(vs, protocol_client_init, 1);
2531 static void make_challenge(VncState *vs)
2533 int i;
2535 srand(time(NULL)+getpid()+getpid()*987654+rand());
2537 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2538 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2541 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2543 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2544 int i, j, pwlen;
2545 unsigned char key[8];
2546 time_t now = time(NULL);
2548 if (!vs->vd->password) {
2549 VNC_DEBUG("No password configured on server");
2550 goto reject;
2552 if (vs->vd->expires < now) {
2553 VNC_DEBUG("Password is expired");
2554 goto reject;
2557 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2559 /* Calculate the expected challenge response */
2560 pwlen = strlen(vs->vd->password);
2561 for (i=0; i<sizeof(key); i++)
2562 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2563 deskey(key, EN0);
2564 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
2565 des(response+j, response+j);
2567 /* Compare expected vs actual challenge response */
2568 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2569 VNC_DEBUG("Client challenge response did not match\n");
2570 goto reject;
2571 } else {
2572 VNC_DEBUG("Accepting VNC challenge response\n");
2573 vnc_write_u32(vs, 0); /* Accept auth */
2574 vnc_flush(vs);
2576 start_client_init(vs);
2578 return 0;
2580 reject:
2581 vnc_write_u32(vs, 1); /* Reject auth */
2582 if (vs->minor >= 8) {
2583 static const char err[] = "Authentication failed";
2584 vnc_write_u32(vs, sizeof(err));
2585 vnc_write(vs, err, sizeof(err));
2587 vnc_flush(vs);
2588 vnc_client_error(vs);
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 #ifdef CONFIG_VNC_TLS
2634 case VNC_AUTH_VENCRYPT:
2635 VNC_DEBUG("Accept VeNCrypt auth\n");
2636 start_auth_vencrypt(vs);
2637 break;
2638 #endif /* CONFIG_VNC_TLS */
2640 #ifdef CONFIG_VNC_SASL
2641 case VNC_AUTH_SASL:
2642 VNC_DEBUG("Accept SASL auth\n");
2643 start_auth_sasl(vs);
2644 break;
2645 #endif /* CONFIG_VNC_SASL */
2647 default: /* Should not be possible, but just in case */
2648 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2649 vnc_write_u8(vs, 1);
2650 if (vs->minor >= 8) {
2651 static const char err[] = "Authentication failed";
2652 vnc_write_u32(vs, sizeof(err));
2653 vnc_write(vs, err, sizeof(err));
2655 vnc_client_error(vs);
2658 return 0;
2661 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2663 char local[13];
2665 memcpy(local, version, 12);
2666 local[12] = 0;
2668 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2669 VNC_DEBUG("Malformed protocol version %s\n", local);
2670 vnc_client_error(vs);
2671 return 0;
2673 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2674 if (vs->major != 3 ||
2675 (vs->minor != 3 &&
2676 vs->minor != 4 &&
2677 vs->minor != 5 &&
2678 vs->minor != 7 &&
2679 vs->minor != 8)) {
2680 VNC_DEBUG("Unsupported client version\n");
2681 vnc_write_u32(vs, VNC_AUTH_INVALID);
2682 vnc_flush(vs);
2683 vnc_client_error(vs);
2684 return 0;
2686 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2687 * as equivalent to v3.3 by servers
2689 if (vs->minor == 4 || vs->minor == 5)
2690 vs->minor = 3;
2692 if (vs->minor == 3) {
2693 if (vs->auth == VNC_AUTH_NONE) {
2694 VNC_DEBUG("Tell client auth none\n");
2695 vnc_write_u32(vs, vs->auth);
2696 vnc_flush(vs);
2697 start_client_init(vs);
2698 } else if (vs->auth == VNC_AUTH_VNC) {
2699 VNC_DEBUG("Tell client VNC auth\n");
2700 vnc_write_u32(vs, vs->auth);
2701 vnc_flush(vs);
2702 start_auth_vnc(vs);
2703 } else {
2704 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2705 vnc_write_u32(vs, VNC_AUTH_INVALID);
2706 vnc_flush(vs);
2707 vnc_client_error(vs);
2709 } else {
2710 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2711 vnc_write_u8(vs, 1); /* num auth */
2712 vnc_write_u8(vs, vs->auth);
2713 vnc_read_when(vs, protocol_client_auth, 1);
2714 vnc_flush(vs);
2717 return 0;
2720 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2722 struct VncSurface *vs = &vd->guest;
2724 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2727 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2729 int i, j;
2731 w = (x + w) / VNC_STAT_RECT;
2732 h = (y + h) / VNC_STAT_RECT;
2733 x /= VNC_STAT_RECT;
2734 y /= VNC_STAT_RECT;
2736 for (j = y; j <= h; j++) {
2737 for (i = x; i <= w; i++) {
2738 vs->lossy_rect[j][i] = 1;
2743 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2745 VncState *vs;
2746 int sty = y / VNC_STAT_RECT;
2747 int stx = x / VNC_STAT_RECT;
2748 int has_dirty = 0;
2750 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2751 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2753 QTAILQ_FOREACH(vs, &vd->clients, next) {
2754 int j;
2756 /* kernel send buffers are full -> refresh later */
2757 if (vs->output.offset) {
2758 continue;
2761 if (!vs->lossy_rect[sty][stx]) {
2762 continue;
2765 vs->lossy_rect[sty][stx] = 0;
2766 for (j = 0; j < VNC_STAT_RECT; ++j) {
2767 bitmap_set(vs->dirty[y + j],
2768 x / VNC_DIRTY_PIXELS_PER_BIT,
2769 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2771 has_dirty++;
2774 return has_dirty;
2777 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2779 int width = pixman_image_get_width(vd->guest.fb);
2780 int height = pixman_image_get_height(vd->guest.fb);
2781 int x, y;
2782 struct timeval res;
2783 int has_dirty = 0;
2785 for (y = 0; y < height; y += VNC_STAT_RECT) {
2786 for (x = 0; x < width; x += VNC_STAT_RECT) {
2787 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2789 rect->updated = false;
2793 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2795 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2796 return has_dirty;
2798 vd->guest.last_freq_check = *tv;
2800 for (y = 0; y < height; y += VNC_STAT_RECT) {
2801 for (x = 0; x < width; x += VNC_STAT_RECT) {
2802 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2803 int count = ARRAY_SIZE(rect->times);
2804 struct timeval min, max;
2806 if (!timerisset(&rect->times[count - 1])) {
2807 continue ;
2810 max = rect->times[(rect->idx + count - 1) % count];
2811 qemu_timersub(tv, &max, &res);
2813 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2814 rect->freq = 0;
2815 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2816 memset(rect->times, 0, sizeof (rect->times));
2817 continue ;
2820 min = rect->times[rect->idx];
2821 max = rect->times[(rect->idx + count - 1) % count];
2822 qemu_timersub(&max, &min, &res);
2824 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2825 rect->freq /= count;
2826 rect->freq = 1. / rect->freq;
2829 return has_dirty;
2832 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2834 int i, j;
2835 double total = 0;
2836 int num = 0;
2838 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2839 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2841 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2842 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2843 total += vnc_stat_rect(vs->vd, i, j)->freq;
2844 num++;
2848 if (num) {
2849 return total / num;
2850 } else {
2851 return 0;
2855 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2857 VncRectStat *rect;
2859 rect = vnc_stat_rect(vd, x, y);
2860 if (rect->updated) {
2861 return ;
2863 rect->times[rect->idx] = *tv;
2864 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2865 rect->updated = true;
2868 static int vnc_refresh_server_surface(VncDisplay *vd)
2870 int width = MIN(pixman_image_get_width(vd->guest.fb),
2871 pixman_image_get_width(vd->server));
2872 int height = MIN(pixman_image_get_height(vd->guest.fb),
2873 pixman_image_get_height(vd->server));
2874 int cmp_bytes, server_stride, min_stride, guest_stride, y = 0;
2875 uint8_t *guest_row0 = NULL, *server_row0;
2876 VncState *vs;
2877 int has_dirty = 0;
2878 pixman_image_t *tmpbuf = NULL;
2880 struct timeval tv = { 0, 0 };
2882 if (!vd->non_adaptive) {
2883 gettimeofday(&tv, NULL);
2884 has_dirty = vnc_update_stats(vd, &tv);
2888 * Walk through the guest dirty map.
2889 * Check and copy modified bits from guest to server surface.
2890 * Update server dirty map.
2892 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2893 server_stride = guest_stride = pixman_image_get_stride(vd->server);
2894 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2895 server_stride);
2896 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2897 int width = pixman_image_get_width(vd->server);
2898 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2899 } else {
2900 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2901 guest_stride = pixman_image_get_stride(vd->guest.fb);
2903 min_stride = MIN(server_stride, guest_stride);
2905 for (;;) {
2906 int x;
2907 uint8_t *guest_ptr, *server_ptr;
2908 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2909 height * VNC_DIRTY_BPL(&vd->guest),
2910 y * VNC_DIRTY_BPL(&vd->guest));
2911 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2912 /* no more dirty bits */
2913 break;
2915 y = offset / VNC_DIRTY_BPL(&vd->guest);
2916 x = offset % VNC_DIRTY_BPL(&vd->guest);
2918 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2920 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2921 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2922 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2923 } else {
2924 guest_ptr = guest_row0 + y * guest_stride;
2926 guest_ptr += x * cmp_bytes;
2928 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2929 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2930 int _cmp_bytes = cmp_bytes;
2931 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2932 continue;
2934 if ((x + 1) * cmp_bytes > min_stride) {
2935 _cmp_bytes = min_stride - x * cmp_bytes;
2937 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2938 continue;
2940 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2941 if (!vd->non_adaptive) {
2942 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2943 y, &tv);
2945 QTAILQ_FOREACH(vs, &vd->clients, next) {
2946 set_bit(x, vs->dirty[y]);
2948 has_dirty++;
2951 y++;
2953 qemu_pixman_image_unref(tmpbuf);
2954 return has_dirty;
2957 static void vnc_refresh(DisplayChangeListener *dcl)
2959 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2960 VncState *vs, *vn;
2961 int has_dirty, rects = 0;
2963 if (QTAILQ_EMPTY(&vd->clients)) {
2964 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2965 return;
2968 graphic_hw_update(vd->dcl.con);
2970 if (vnc_trylock_display(vd)) {
2971 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2972 return;
2975 has_dirty = vnc_refresh_server_surface(vd);
2976 vnc_unlock_display(vd);
2978 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2979 rects += vnc_update_client(vs, has_dirty, false);
2980 /* vs might be free()ed here */
2983 if (has_dirty && rects) {
2984 vd->dcl.update_interval /= 2;
2985 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2986 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2988 } else {
2989 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2990 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2991 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2996 static void vnc_connect(VncDisplay *vd, int csock,
2997 bool skipauth, bool websocket)
2999 VncState *vs = g_malloc0(sizeof(VncState));
3000 int i;
3002 vs->csock = csock;
3003 vs->vd = vd;
3005 if (skipauth) {
3006 vs->auth = VNC_AUTH_NONE;
3007 #ifdef CONFIG_VNC_TLS
3008 vs->subauth = VNC_AUTH_INVALID;
3009 #endif
3010 } else {
3011 vs->auth = vd->auth;
3012 #ifdef CONFIG_VNC_TLS
3013 vs->subauth = vd->subauth;
3014 #endif
3017 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3018 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3019 vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));
3022 VNC_DEBUG("New client on socket %d\n", csock);
3023 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3024 qemu_set_nonblock(vs->csock);
3025 #ifdef CONFIG_VNC_WS
3026 if (websocket) {
3027 vs->websocket = 1;
3028 #ifdef CONFIG_VNC_TLS
3029 if (vd->tls.x509cert) {
3030 qemu_set_fd_handler2(vs->csock, NULL, vncws_tls_handshake_peek,
3031 NULL, vs);
3032 } else
3033 #endif /* CONFIG_VNC_TLS */
3035 qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read,
3036 NULL, vs);
3038 } else
3039 #endif /* CONFIG_VNC_WS */
3041 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
3044 vnc_client_cache_addr(vs);
3045 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3046 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3048 #ifdef CONFIG_VNC_WS
3049 if (!vs->websocket)
3050 #endif
3052 vnc_init_state(vs);
3055 if (vd->num_connecting > vd->connections_limit) {
3056 QTAILQ_FOREACH(vs, &vd->clients, next) {
3057 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3058 vnc_disconnect_start(vs);
3059 return;
3065 void vnc_init_state(VncState *vs)
3067 vs->initialized = true;
3068 VncDisplay *vd = vs->vd;
3070 vs->last_x = -1;
3071 vs->last_y = -1;
3073 vs->as.freq = 44100;
3074 vs->as.nchannels = 2;
3075 vs->as.fmt = AUD_FMT_S16;
3076 vs->as.endianness = 0;
3078 qemu_mutex_init(&vs->output_mutex);
3079 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3081 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3083 graphic_hw_update(vd->dcl.con);
3085 vnc_write(vs, "RFB 003.008\n", 12);
3086 vnc_flush(vs);
3087 vnc_read_when(vs, protocol_version, 12);
3088 reset_keys(vs);
3089 if (vs->vd->lock_key_sync)
3090 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3092 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3093 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3095 /* vs might be free()ed here */
3098 static void vnc_listen_read(void *opaque, bool websocket)
3100 VncDisplay *vs = opaque;
3101 struct sockaddr_in addr;
3102 socklen_t addrlen = sizeof(addr);
3103 int csock;
3105 /* Catch-up */
3106 graphic_hw_update(vs->dcl.con);
3107 #ifdef CONFIG_VNC_WS
3108 if (websocket) {
3109 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
3110 } else
3111 #endif /* CONFIG_VNC_WS */
3113 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
3116 if (csock != -1) {
3117 socket_set_nodelay(csock);
3118 vnc_connect(vs, csock, false, websocket);
3122 static void vnc_listen_regular_read(void *opaque)
3124 vnc_listen_read(opaque, false);
3127 #ifdef CONFIG_VNC_WS
3128 static void vnc_listen_websocket_read(void *opaque)
3130 vnc_listen_read(opaque, true);
3132 #endif /* CONFIG_VNC_WS */
3134 static const DisplayChangeListenerOps dcl_ops = {
3135 .dpy_name = "vnc",
3136 .dpy_refresh = vnc_refresh,
3137 .dpy_gfx_copy = vnc_dpy_copy,
3138 .dpy_gfx_update = vnc_dpy_update,
3139 .dpy_gfx_switch = vnc_dpy_switch,
3140 .dpy_gfx_check_format = qemu_pixman_check_format,
3141 .dpy_mouse_set = vnc_mouse_set,
3142 .dpy_cursor_define = vnc_dpy_cursor_define,
3145 void vnc_display_init(const char *id)
3147 VncDisplay *vs;
3149 if (vnc_display_find(id) != NULL) {
3150 return;
3152 vs = g_malloc0(sizeof(*vs));
3154 vs->id = strdup(id);
3155 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3157 vs->lsock = -1;
3158 #ifdef CONFIG_VNC_WS
3159 vs->lwebsock = -1;
3160 #endif
3162 QTAILQ_INIT(&vs->clients);
3163 vs->expires = TIME_MAX;
3165 if (keyboard_layout) {
3166 trace_vnc_key_map_init(keyboard_layout);
3167 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3168 } else {
3169 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3172 if (!vs->kbd_layout)
3173 exit(1);
3175 qemu_mutex_init(&vs->mutex);
3176 vnc_start_worker_thread();
3178 vs->dcl.ops = &dcl_ops;
3179 register_displaychangelistener(&vs->dcl);
3183 static void vnc_display_close(VncDisplay *vs)
3185 if (!vs)
3186 return;
3187 g_free(vs->display);
3188 vs->display = NULL;
3189 if (vs->lsock != -1) {
3190 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
3191 close(vs->lsock);
3192 vs->lsock = -1;
3194 #ifdef CONFIG_VNC_WS
3195 g_free(vs->ws_display);
3196 vs->ws_display = NULL;
3197 if (vs->lwebsock != -1) {
3198 qemu_set_fd_handler2(vs->lwebsock, NULL, NULL, NULL, NULL);
3199 close(vs->lwebsock);
3200 vs->lwebsock = -1;
3202 #endif /* CONFIG_VNC_WS */
3203 vs->auth = VNC_AUTH_INVALID;
3204 #ifdef CONFIG_VNC_TLS
3205 vs->subauth = VNC_AUTH_INVALID;
3206 vs->tls.x509verify = 0;
3207 #endif
3210 int vnc_display_password(const char *id, const char *password)
3212 VncDisplay *vs = vnc_display_find(id);
3214 if (!vs) {
3215 return -EINVAL;
3217 if (vs->auth == VNC_AUTH_NONE) {
3218 error_printf_unless_qmp("If you want use passwords please enable "
3219 "password auth using '-vnc ${dpy},password'.");
3220 return -EINVAL;
3223 g_free(vs->password);
3224 vs->password = g_strdup(password);
3226 return 0;
3229 int vnc_display_pw_expire(const char *id, time_t expires)
3231 VncDisplay *vs = vnc_display_find(id);
3233 if (!vs) {
3234 return -EINVAL;
3237 vs->expires = expires;
3238 return 0;
3241 char *vnc_display_local_addr(const char *id)
3243 VncDisplay *vs = vnc_display_find(id);
3245 return vnc_socket_local_addr("%s:%s", vs->lsock);
3248 static QemuOptsList qemu_vnc_opts = {
3249 .name = "vnc",
3250 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3251 .implied_opt_name = "vnc",
3252 .desc = {
3254 .name = "vnc",
3255 .type = QEMU_OPT_STRING,
3257 .name = "websocket",
3258 .type = QEMU_OPT_STRING,
3260 .name = "x509",
3261 .type = QEMU_OPT_STRING,
3263 .name = "share",
3264 .type = QEMU_OPT_STRING,
3266 .name = "display",
3267 .type = QEMU_OPT_STRING,
3269 .name = "head",
3270 .type = QEMU_OPT_NUMBER,
3272 .name = "connections",
3273 .type = QEMU_OPT_NUMBER,
3275 .name = "password",
3276 .type = QEMU_OPT_BOOL,
3278 .name = "reverse",
3279 .type = QEMU_OPT_BOOL,
3281 .name = "lock-key-sync",
3282 .type = QEMU_OPT_BOOL,
3284 .name = "sasl",
3285 .type = QEMU_OPT_BOOL,
3287 .name = "tls",
3288 .type = QEMU_OPT_BOOL,
3290 .name = "x509verify",
3291 .type = QEMU_OPT_BOOL,
3293 .name = "acl",
3294 .type = QEMU_OPT_BOOL,
3296 .name = "lossy",
3297 .type = QEMU_OPT_BOOL,
3299 .name = "non-adaptive",
3300 .type = QEMU_OPT_BOOL,
3302 { /* end of list */ }
3306 void vnc_display_open(const char *id, Error **errp)
3308 VncDisplay *vs = vnc_display_find(id);
3309 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3310 const char *display, *share, *device_id;
3311 QemuConsole *con;
3312 int password = 0;
3313 int reverse = 0;
3314 #ifdef CONFIG_VNC_WS
3315 const char *websocket;
3316 #endif
3317 #ifdef CONFIG_VNC_TLS
3318 int tls = 0, x509 = 0;
3319 const char *path;
3320 #endif
3321 #ifdef CONFIG_VNC_SASL
3322 int sasl = 0;
3323 int saslErr;
3324 #endif
3325 #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
3326 int acl = 0;
3327 #endif
3328 int lock_key_sync = 1;
3330 if (!vs) {
3331 error_setg(errp, "VNC display not active");
3332 return;
3334 vnc_display_close(vs);
3336 if (!opts) {
3337 return;
3339 display = qemu_opt_get(opts, "vnc");
3340 if (!display || strcmp(display, "none") == 0) {
3341 return;
3343 vs->display = g_strdup(display);
3345 password = qemu_opt_get_bool(opts, "password", false);
3346 if (password && fips_get_state()) {
3347 error_setg(errp,
3348 "VNC password auth disabled due to FIPS mode, "
3349 "consider using the VeNCrypt or SASL authentication "
3350 "methods as an alternative");
3351 goto fail;
3354 reverse = qemu_opt_get_bool(opts, "reverse", false);
3355 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3356 #ifdef CONFIG_VNC_SASL
3357 sasl = qemu_opt_get_bool(opts, "sasl", false);
3358 #endif
3359 #ifdef CONFIG_VNC_TLS
3360 tls = qemu_opt_get_bool(opts, "tls", false);
3361 path = qemu_opt_get(opts, "x509");
3362 if (path) {
3363 x509 = 1;
3364 vs->tls.x509verify = qemu_opt_get_bool(opts, "x509verify", false);
3365 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
3366 error_setg(errp, "Failed to find x509 certificates/keys in %s",
3367 path);
3368 goto fail;
3371 #endif
3372 #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
3373 acl = qemu_opt_get_bool(opts, "acl", false);
3374 #endif
3376 share = qemu_opt_get(opts, "share");
3377 if (share) {
3378 if (strcmp(share, "ignore") == 0) {
3379 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3380 } else if (strcmp(share, "allow-exclusive") == 0) {
3381 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3382 } else if (strcmp(share, "force-shared") == 0) {
3383 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3384 } else {
3385 error_setg(errp, "unknown vnc share= option");
3386 goto fail;
3388 } else {
3389 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3391 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3393 #ifdef CONFIG_VNC_WS
3394 websocket = qemu_opt_get(opts, "websocket");
3395 if (websocket) {
3396 /* extract the host specification from display */
3397 char *host = NULL, *host_end = NULL;
3398 vs->websocket = 1;
3400 /* ipv6 hosts have colons */
3401 host_end = strrchr(display, ':');
3402 if (host_end) {
3403 host = g_strndup(display, host_end - display + 1);
3404 } else {
3405 host = g_strdup(":");
3407 vs->ws_display = g_strconcat(host, websocket, NULL);
3408 g_free(host);
3410 #endif /* CONFIG_VNC_WS */
3412 #ifdef CONFIG_VNC_JPEG
3413 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3414 #endif
3415 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3416 /* adaptive updates are only used with tight encoding and
3417 * if lossy updates are enabled so we can disable all the
3418 * calculations otherwise */
3419 if (!vs->lossy) {
3420 vs->non_adaptive = true;
3423 #ifdef CONFIG_VNC_TLS
3424 if (acl && x509 && vs->tls.x509verify) {
3425 char *aclname;
3427 if (strcmp(vs->id, "default") == 0) {
3428 aclname = g_strdup("vnc.x509dname");
3429 } else {
3430 aclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3432 vs->tls.acl = qemu_acl_init(aclname);
3433 if (!vs->tls.acl) {
3434 fprintf(stderr, "Failed to create x509 dname ACL\n");
3435 exit(1);
3437 g_free(aclname);
3439 #endif
3440 #ifdef CONFIG_VNC_SASL
3441 if (acl && sasl) {
3442 char *aclname;
3444 if (strcmp(vs->id, "default") == 0) {
3445 aclname = g_strdup("vnc.username");
3446 } else {
3447 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3449 vs->sasl.acl = qemu_acl_init(aclname);
3450 if (!vs->sasl.acl) {
3451 fprintf(stderr, "Failed to create username ACL\n");
3452 exit(1);
3454 g_free(aclname);
3456 #endif
3459 * Combinations we support here:
3461 * - no-auth (clear text, no auth)
3462 * - password (clear text, weak auth)
3463 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
3464 * - tls (encrypt, weak anonymous creds, no auth)
3465 * - tls + password (encrypt, weak anonymous creds, weak auth)
3466 * - tls + sasl (encrypt, weak anonymous creds, good auth)
3467 * - tls + x509 (encrypt, good x509 creds, no auth)
3468 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
3469 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
3471 * NB1. TLS is a stackable auth scheme.
3472 * NB2. the x509 schemes have option to validate a client cert dname
3474 if (password) {
3475 #ifdef CONFIG_VNC_TLS
3476 if (tls) {
3477 vs->auth = VNC_AUTH_VENCRYPT;
3478 if (x509) {
3479 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3480 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3481 } else {
3482 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3483 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3485 } else {
3486 #endif /* CONFIG_VNC_TLS */
3487 VNC_DEBUG("Initializing VNC server with password auth\n");
3488 vs->auth = VNC_AUTH_VNC;
3489 #ifdef CONFIG_VNC_TLS
3490 vs->subauth = VNC_AUTH_INVALID;
3492 #endif /* CONFIG_VNC_TLS */
3493 #ifdef CONFIG_VNC_SASL
3494 } else if (sasl) {
3495 #ifdef CONFIG_VNC_TLS
3496 if (tls) {
3497 vs->auth = VNC_AUTH_VENCRYPT;
3498 if (x509) {
3499 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3500 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3501 } else {
3502 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3503 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3505 } else {
3506 #endif /* CONFIG_VNC_TLS */
3507 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3508 vs->auth = VNC_AUTH_SASL;
3509 #ifdef CONFIG_VNC_TLS
3510 vs->subauth = VNC_AUTH_INVALID;
3512 #endif /* CONFIG_VNC_TLS */
3513 #endif /* CONFIG_VNC_SASL */
3514 } else {
3515 #ifdef CONFIG_VNC_TLS
3516 if (tls) {
3517 vs->auth = VNC_AUTH_VENCRYPT;
3518 if (x509) {
3519 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3520 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3521 } else {
3522 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3523 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3525 } else {
3526 #endif
3527 VNC_DEBUG("Initializing VNC server with no auth\n");
3528 vs->auth = VNC_AUTH_NONE;
3529 #ifdef CONFIG_VNC_TLS
3530 vs->subauth = VNC_AUTH_INVALID;
3532 #endif
3535 #ifdef CONFIG_VNC_SASL
3536 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3537 error_setg(errp, "Failed to initialize SASL auth: %s",
3538 sasl_errstring(saslErr, NULL, NULL));
3539 goto fail;
3541 #endif
3542 vs->lock_key_sync = lock_key_sync;
3544 device_id = qemu_opt_get(opts, "display");
3545 if (device_id) {
3546 DeviceState *dev;
3547 int head = qemu_opt_get_number(opts, "head", 0);
3549 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3550 if (dev == NULL) {
3551 error_set(errp, QERR_DEVICE_NOT_FOUND, device_id);
3552 goto fail;
3555 con = qemu_console_lookup_by_device(dev, head);
3556 if (con == NULL) {
3557 error_setg(errp, "Device %s is not bound to a QemuConsole",
3558 device_id);
3559 goto fail;
3561 } else {
3562 con = NULL;
3565 if (con != vs->dcl.con) {
3566 unregister_displaychangelistener(&vs->dcl);
3567 vs->dcl.con = con;
3568 register_displaychangelistener(&vs->dcl);
3571 if (reverse) {
3572 /* connect to viewer */
3573 int csock;
3574 vs->lsock = -1;
3575 #ifdef CONFIG_VNC_WS
3576 vs->lwebsock = -1;
3577 #endif
3578 if (strncmp(display, "unix:", 5) == 0) {
3579 csock = unix_connect(display+5, errp);
3580 } else {
3581 csock = inet_connect(display, errp);
3583 if (csock < 0) {
3584 goto fail;
3586 vnc_connect(vs, csock, false, false);
3587 } else {
3588 /* listen for connects */
3589 char *dpy;
3590 dpy = g_malloc(256);
3591 if (strncmp(display, "unix:", 5) == 0) {
3592 pstrcpy(dpy, 256, "unix:");
3593 vs->lsock = unix_listen(display+5, dpy+5, 256-5, errp);
3594 } else {
3595 vs->lsock = inet_listen(display, dpy, 256,
3596 SOCK_STREAM, 5900, errp);
3597 if (vs->lsock < 0) {
3598 g_free(dpy);
3599 goto fail;
3601 #ifdef CONFIG_VNC_WS
3602 if (vs->websocket) {
3603 if (vs->ws_display) {
3604 vs->lwebsock = inet_listen(vs->ws_display, NULL, 256,
3605 SOCK_STREAM, 0, errp);
3606 } else {
3607 vs->lwebsock = inet_listen(vs->display, NULL, 256,
3608 SOCK_STREAM, 5700, errp);
3611 if (vs->lwebsock < 0) {
3612 if (vs->lsock) {
3613 close(vs->lsock);
3614 vs->lsock = -1;
3616 g_free(dpy);
3617 goto fail;
3620 #endif /* CONFIG_VNC_WS */
3622 g_free(vs->display);
3623 vs->display = dpy;
3624 qemu_set_fd_handler2(vs->lsock, NULL,
3625 vnc_listen_regular_read, NULL, vs);
3626 #ifdef CONFIG_VNC_WS
3627 if (vs->websocket) {
3628 qemu_set_fd_handler2(vs->lwebsock, NULL,
3629 vnc_listen_websocket_read, NULL, vs);
3631 #endif /* CONFIG_VNC_WS */
3633 return;
3635 fail:
3636 g_free(vs->display);
3637 vs->display = NULL;
3638 #ifdef CONFIG_VNC_WS
3639 g_free(vs->ws_display);
3640 vs->ws_display = NULL;
3641 #endif /* CONFIG_VNC_WS */
3644 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3646 VncDisplay *vs = vnc_display_find(id);
3648 if (!vs) {
3649 return;
3651 vnc_connect(vs, csock, skipauth, false);
3654 QemuOpts *vnc_parse_func(const char *str)
3656 return qemu_opts_parse(qemu_find_opts("vnc"), str, 1);
3659 int vnc_init_func(QemuOpts *opts, void *opaque)
3661 Error *local_err = NULL;
3662 QemuOptsList *olist = qemu_find_opts("vnc");
3663 char *id = (char *)qemu_opts_id(opts);
3665 if (!id) {
3666 /* auto-assign id if not present */
3667 int i = 2;
3668 id = g_strdup("default");
3669 while (qemu_opts_find(olist, id)) {
3670 g_free(id);
3671 id = g_strdup_printf("vnc%d", i++);
3673 qemu_opts_set_id(opts, id);
3676 vnc_display_init(id);
3677 vnc_display_open(id, &local_err);
3678 if (local_err != NULL) {
3679 error_report("Failed to start VNC server on `%s': %s",
3680 qemu_opt_get(opts, "display"),
3681 error_get_pretty(local_err));
3682 error_free(local_err);
3683 exit(1);
3685 return 0;
3688 static void vnc_register_config(void)
3690 qemu_add_opts(&qemu_vnc_opts);
3692 machine_init(vnc_register_config);