target-i386: Eliminate cpu_init() function
[qemu/ar7.git] / ui / vnc.c
blob10a272450b1bd527f43036dbef2e5a153af7c1bb
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);
1114 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1115 y += h;
1116 if (y == height) {
1117 break;
1122 vnc_job_push(job);
1123 if (sync) {
1124 vnc_jobs_join(vs);
1126 vs->force_update = 0;
1127 vs->has_dirty = 0;
1128 return n;
1131 if (vs->csock == -1) {
1132 vnc_disconnect_finish(vs);
1133 } else if (sync) {
1134 vnc_jobs_join(vs);
1137 return 0;
1140 /* audio */
1141 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1143 VncState *vs = opaque;
1145 switch (cmd) {
1146 case AUD_CNOTIFY_DISABLE:
1147 vnc_lock_output(vs);
1148 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1149 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1150 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1151 vnc_unlock_output(vs);
1152 vnc_flush(vs);
1153 break;
1155 case AUD_CNOTIFY_ENABLE:
1156 vnc_lock_output(vs);
1157 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1158 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1159 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1160 vnc_unlock_output(vs);
1161 vnc_flush(vs);
1162 break;
1166 static void audio_capture_destroy(void *opaque)
1170 static void audio_capture(void *opaque, void *buf, int size)
1172 VncState *vs = opaque;
1174 vnc_lock_output(vs);
1175 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1176 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1177 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1178 vnc_write_u32(vs, size);
1179 vnc_write(vs, buf, size);
1180 vnc_unlock_output(vs);
1181 vnc_flush(vs);
1184 static void audio_add(VncState *vs)
1186 struct audio_capture_ops ops;
1188 if (vs->audio_cap) {
1189 error_report("audio already running");
1190 return;
1193 ops.notify = audio_capture_notify;
1194 ops.destroy = audio_capture_destroy;
1195 ops.capture = audio_capture;
1197 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
1198 if (!vs->audio_cap) {
1199 error_report("Failed to add audio capture");
1203 static void audio_del(VncState *vs)
1205 if (vs->audio_cap) {
1206 AUD_del_capture(vs->audio_cap, vs);
1207 vs->audio_cap = NULL;
1211 static void vnc_disconnect_start(VncState *vs)
1213 if (vs->csock == -1)
1214 return;
1215 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1216 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
1217 closesocket(vs->csock);
1218 vs->csock = -1;
1221 void vnc_disconnect_finish(VncState *vs)
1223 int i;
1225 vnc_jobs_join(vs); /* Wait encoding jobs */
1227 vnc_lock_output(vs);
1228 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1230 buffer_free(&vs->input);
1231 buffer_free(&vs->output);
1232 #ifdef CONFIG_VNC_WS
1233 buffer_free(&vs->ws_input);
1234 buffer_free(&vs->ws_output);
1235 #endif /* CONFIG_VNC_WS */
1237 qapi_free_VncClientInfo(vs->info);
1239 vnc_zlib_clear(vs);
1240 vnc_tight_clear(vs);
1241 vnc_zrle_clear(vs);
1243 #ifdef CONFIG_VNC_TLS
1244 vnc_tls_client_cleanup(vs);
1245 #endif /* CONFIG_VNC_TLS */
1246 #ifdef CONFIG_VNC_SASL
1247 vnc_sasl_client_cleanup(vs);
1248 #endif /* CONFIG_VNC_SASL */
1249 audio_del(vs);
1250 vnc_release_modifiers(vs);
1252 if (vs->initialized) {
1253 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1254 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1257 if (vs->vd->lock_key_sync)
1258 qemu_remove_led_event_handler(vs->led);
1259 vnc_unlock_output(vs);
1261 qemu_mutex_destroy(&vs->output_mutex);
1262 if (vs->bh != NULL) {
1263 qemu_bh_delete(vs->bh);
1265 buffer_free(&vs->jobs_buffer);
1267 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1268 g_free(vs->lossy_rect[i]);
1270 g_free(vs->lossy_rect);
1271 g_free(vs);
1274 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
1276 if (ret == 0 || ret == -1) {
1277 if (ret == -1) {
1278 switch (last_errno) {
1279 case EINTR:
1280 case EAGAIN:
1281 #ifdef _WIN32
1282 case WSAEWOULDBLOCK:
1283 #endif
1284 return 0;
1285 default:
1286 break;
1290 VNC_DEBUG("Closing down client sock: ret %d, errno %d\n",
1291 ret, ret < 0 ? last_errno : 0);
1292 vnc_disconnect_start(vs);
1294 return 0;
1296 return ret;
1300 void vnc_client_error(VncState *vs)
1302 VNC_DEBUG("Closing down client sock: protocol error\n");
1303 vnc_disconnect_start(vs);
1306 #ifdef CONFIG_VNC_TLS
1307 static long vnc_client_write_tls(gnutls_session_t *session,
1308 const uint8_t *data,
1309 size_t datalen)
1311 long ret = gnutls_write(*session, data, datalen);
1312 if (ret < 0) {
1313 if (ret == GNUTLS_E_AGAIN) {
1314 errno = EAGAIN;
1315 } else {
1316 errno = EIO;
1318 ret = -1;
1320 return ret;
1322 #endif /* CONFIG_VNC_TLS */
1325 * Called to write a chunk of data to the client socket. The data may
1326 * be the raw data, or may have already been encoded by SASL.
1327 * The data will be written either straight onto the socket, or
1328 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1330 * NB, it is theoretically possible to have 2 layers of encryption,
1331 * both SASL, and this TLS layer. It is highly unlikely in practice
1332 * though, since SASL encryption will typically be a no-op if TLS
1333 * is active
1335 * Returns the number of bytes written, which may be less than
1336 * the requested 'datalen' if the socket would block. Returns
1337 * -1 on error, and disconnects the client socket.
1339 long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1341 long ret;
1342 #ifdef CONFIG_VNC_TLS
1343 if (vs->tls.session) {
1344 ret = vnc_client_write_tls(&vs->tls.session, data, datalen);
1345 } else {
1346 #ifdef CONFIG_VNC_WS
1347 if (vs->ws_tls.session) {
1348 ret = vnc_client_write_tls(&vs->ws_tls.session, data, datalen);
1349 } else
1350 #endif /* CONFIG_VNC_WS */
1351 #endif /* CONFIG_VNC_TLS */
1353 ret = send(vs->csock, (const void *)data, datalen, 0);
1355 #ifdef CONFIG_VNC_TLS
1357 #endif /* CONFIG_VNC_TLS */
1358 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1359 return vnc_client_io_error(vs, ret, socket_error());
1364 * Called to write buffered data to the client socket, when not
1365 * using any SASL SSF encryption layers. Will write as much data
1366 * as possible without blocking. If all buffered data is written,
1367 * will switch the FD poll() handler back to read monitoring.
1369 * Returns the number of bytes written, which may be less than
1370 * the buffered output data if the socket would block. Returns
1371 * -1 on error, and disconnects the client socket.
1373 static long vnc_client_write_plain(VncState *vs)
1375 long ret;
1377 #ifdef CONFIG_VNC_SASL
1378 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1379 vs->output.buffer, vs->output.capacity, vs->output.offset,
1380 vs->sasl.waitWriteSSF);
1382 if (vs->sasl.conn &&
1383 vs->sasl.runSSF &&
1384 vs->sasl.waitWriteSSF) {
1385 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1386 if (ret)
1387 vs->sasl.waitWriteSSF -= ret;
1388 } else
1389 #endif /* CONFIG_VNC_SASL */
1390 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1391 if (!ret)
1392 return 0;
1394 buffer_advance(&vs->output, ret);
1396 if (vs->output.offset == 0) {
1397 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1400 return ret;
1405 * First function called whenever there is data to be written to
1406 * the client socket. Will delegate actual work according to whether
1407 * SASL SSF layers are enabled (thus requiring encryption calls)
1409 static void vnc_client_write_locked(void *opaque)
1411 VncState *vs = opaque;
1413 #ifdef CONFIG_VNC_SASL
1414 if (vs->sasl.conn &&
1415 vs->sasl.runSSF &&
1416 !vs->sasl.waitWriteSSF) {
1417 vnc_client_write_sasl(vs);
1418 } else
1419 #endif /* CONFIG_VNC_SASL */
1421 #ifdef CONFIG_VNC_WS
1422 if (vs->encode_ws) {
1423 vnc_client_write_ws(vs);
1424 } else
1425 #endif /* CONFIG_VNC_WS */
1427 vnc_client_write_plain(vs);
1432 void vnc_client_write(void *opaque)
1434 VncState *vs = opaque;
1436 vnc_lock_output(vs);
1437 if (vs->output.offset
1438 #ifdef CONFIG_VNC_WS
1439 || vs->ws_output.offset
1440 #endif
1442 vnc_client_write_locked(opaque);
1443 } else if (vs->csock != -1) {
1444 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1446 vnc_unlock_output(vs);
1449 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1451 vs->read_handler = func;
1452 vs->read_handler_expect = expecting;
1455 #ifdef CONFIG_VNC_TLS
1456 static long vnc_client_read_tls(gnutls_session_t *session, uint8_t *data,
1457 size_t datalen)
1459 long ret = gnutls_read(*session, data, datalen);
1460 if (ret < 0) {
1461 if (ret == GNUTLS_E_AGAIN) {
1462 errno = EAGAIN;
1463 } else {
1464 errno = EIO;
1466 ret = -1;
1468 return ret;
1470 #endif /* CONFIG_VNC_TLS */
1473 * Called to read a chunk of data from the client socket. The data may
1474 * be the raw data, or may need to be further decoded by SASL.
1475 * The data will be read either straight from to the socket, or
1476 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1478 * NB, it is theoretically possible to have 2 layers of encryption,
1479 * both SASL, and this TLS layer. It is highly unlikely in practice
1480 * though, since SASL encryption will typically be a no-op if TLS
1481 * is active
1483 * Returns the number of bytes read, which may be less than
1484 * the requested 'datalen' if the socket would block. Returns
1485 * -1 on error, and disconnects the client socket.
1487 long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1489 long ret;
1490 #ifdef CONFIG_VNC_TLS
1491 if (vs->tls.session) {
1492 ret = vnc_client_read_tls(&vs->tls.session, data, datalen);
1493 } else {
1494 #ifdef CONFIG_VNC_WS
1495 if (vs->ws_tls.session) {
1496 ret = vnc_client_read_tls(&vs->ws_tls.session, data, datalen);
1497 } else
1498 #endif /* CONFIG_VNC_WS */
1499 #endif /* CONFIG_VNC_TLS */
1501 ret = qemu_recv(vs->csock, data, datalen, 0);
1503 #ifdef CONFIG_VNC_TLS
1505 #endif /* CONFIG_VNC_TLS */
1506 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1507 return vnc_client_io_error(vs, ret, socket_error());
1512 * Called to read data from the client socket to the input buffer,
1513 * when not using any SASL SSF encryption layers. Will read as much
1514 * data as possible without blocking.
1516 * Returns the number of bytes read. Returns -1 on error, and
1517 * disconnects the client socket.
1519 static long vnc_client_read_plain(VncState *vs)
1521 int ret;
1522 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1523 vs->input.buffer, vs->input.capacity, vs->input.offset);
1524 buffer_reserve(&vs->input, 4096);
1525 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1526 if (!ret)
1527 return 0;
1528 vs->input.offset += ret;
1529 return ret;
1532 static void vnc_jobs_bh(void *opaque)
1534 VncState *vs = opaque;
1536 vnc_jobs_consume_buffer(vs);
1540 * First function called whenever there is more data to be read from
1541 * the client socket. Will delegate actual work according to whether
1542 * SASL SSF layers are enabled (thus requiring decryption calls)
1544 void vnc_client_read(void *opaque)
1546 VncState *vs = opaque;
1547 long ret;
1549 #ifdef CONFIG_VNC_SASL
1550 if (vs->sasl.conn && vs->sasl.runSSF)
1551 ret = vnc_client_read_sasl(vs);
1552 else
1553 #endif /* CONFIG_VNC_SASL */
1554 #ifdef CONFIG_VNC_WS
1555 if (vs->encode_ws) {
1556 ret = vnc_client_read_ws(vs);
1557 if (ret == -1) {
1558 vnc_disconnect_start(vs);
1559 return;
1560 } else if (ret == -2) {
1561 vnc_client_error(vs);
1562 return;
1564 } else
1565 #endif /* CONFIG_VNC_WS */
1567 ret = vnc_client_read_plain(vs);
1569 if (!ret) {
1570 if (vs->csock == -1)
1571 vnc_disconnect_finish(vs);
1572 return;
1575 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1576 size_t len = vs->read_handler_expect;
1577 int ret;
1579 ret = vs->read_handler(vs, vs->input.buffer, len);
1580 if (vs->csock == -1) {
1581 vnc_disconnect_finish(vs);
1582 return;
1585 if (!ret) {
1586 buffer_advance(&vs->input, len);
1587 } else {
1588 vs->read_handler_expect = ret;
1593 void vnc_write(VncState *vs, const void *data, size_t len)
1595 buffer_reserve(&vs->output, len);
1597 if (vs->csock != -1 && buffer_empty(&vs->output)) {
1598 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1601 buffer_append(&vs->output, data, len);
1604 void vnc_write_s32(VncState *vs, int32_t value)
1606 vnc_write_u32(vs, *(uint32_t *)&value);
1609 void vnc_write_u32(VncState *vs, uint32_t value)
1611 uint8_t buf[4];
1613 buf[0] = (value >> 24) & 0xFF;
1614 buf[1] = (value >> 16) & 0xFF;
1615 buf[2] = (value >> 8) & 0xFF;
1616 buf[3] = value & 0xFF;
1618 vnc_write(vs, buf, 4);
1621 void vnc_write_u16(VncState *vs, uint16_t value)
1623 uint8_t buf[2];
1625 buf[0] = (value >> 8) & 0xFF;
1626 buf[1] = value & 0xFF;
1628 vnc_write(vs, buf, 2);
1631 void vnc_write_u8(VncState *vs, uint8_t value)
1633 vnc_write(vs, (char *)&value, 1);
1636 void vnc_flush(VncState *vs)
1638 vnc_lock_output(vs);
1639 if (vs->csock != -1 && (vs->output.offset
1640 #ifdef CONFIG_VNC_WS
1641 || vs->ws_output.offset
1642 #endif
1643 )) {
1644 vnc_client_write_locked(vs);
1646 vnc_unlock_output(vs);
1649 static uint8_t read_u8(uint8_t *data, size_t offset)
1651 return data[offset];
1654 static uint16_t read_u16(uint8_t *data, size_t offset)
1656 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1659 static int32_t read_s32(uint8_t *data, size_t offset)
1661 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1662 (data[offset + 2] << 8) | data[offset + 3]);
1665 uint32_t read_u32(uint8_t *data, size_t offset)
1667 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1668 (data[offset + 2] << 8) | data[offset + 3]);
1671 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1675 static void check_pointer_type_change(Notifier *notifier, void *data)
1677 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1678 int absolute = qemu_input_is_absolute();
1680 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1681 vnc_lock_output(vs);
1682 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1683 vnc_write_u8(vs, 0);
1684 vnc_write_u16(vs, 1);
1685 vnc_framebuffer_update(vs, absolute, 0,
1686 pixman_image_get_width(vs->vd->server),
1687 pixman_image_get_height(vs->vd->server),
1688 VNC_ENCODING_POINTER_TYPE_CHANGE);
1689 vnc_unlock_output(vs);
1690 vnc_flush(vs);
1692 vs->absolute = absolute;
1695 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1697 static uint32_t bmap[INPUT_BUTTON_MAX] = {
1698 [INPUT_BUTTON_LEFT] = 0x01,
1699 [INPUT_BUTTON_MIDDLE] = 0x02,
1700 [INPUT_BUTTON_RIGHT] = 0x04,
1701 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1702 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1704 QemuConsole *con = vs->vd->dcl.con;
1705 int width = pixman_image_get_width(vs->vd->server);
1706 int height = pixman_image_get_height(vs->vd->server);
1708 if (vs->last_bmask != button_mask) {
1709 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1710 vs->last_bmask = button_mask;
1713 if (vs->absolute) {
1714 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1715 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
1716 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1717 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1718 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1719 } else {
1720 if (vs->last_x != -1) {
1721 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1722 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1724 vs->last_x = x;
1725 vs->last_y = y;
1727 qemu_input_event_sync();
1730 static void reset_keys(VncState *vs)
1732 int i;
1733 for(i = 0; i < 256; i++) {
1734 if (vs->modifiers_state[i]) {
1735 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
1736 vs->modifiers_state[i] = 0;
1741 static void press_key(VncState *vs, int keysym)
1743 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
1744 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
1745 qemu_input_event_send_key_delay(0);
1746 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
1747 qemu_input_event_send_key_delay(0);
1750 static int current_led_state(VncState *vs)
1752 int ledstate = 0;
1754 if (vs->modifiers_state[0x46]) {
1755 ledstate |= QEMU_SCROLL_LOCK_LED;
1757 if (vs->modifiers_state[0x45]) {
1758 ledstate |= QEMU_NUM_LOCK_LED;
1760 if (vs->modifiers_state[0x3a]) {
1761 ledstate |= QEMU_CAPS_LOCK_LED;
1764 return ledstate;
1767 static void vnc_led_state_change(VncState *vs)
1769 int ledstate = 0;
1771 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1772 return;
1775 ledstate = current_led_state(vs);
1776 vnc_lock_output(vs);
1777 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1778 vnc_write_u8(vs, 0);
1779 vnc_write_u16(vs, 1);
1780 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1781 vnc_write_u8(vs, ledstate);
1782 vnc_unlock_output(vs);
1783 vnc_flush(vs);
1786 static void kbd_leds(void *opaque, int ledstate)
1788 VncState *vs = opaque;
1789 int caps, num, scr;
1790 bool has_changed = (ledstate != current_led_state(vs));
1792 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1793 (ledstate & QEMU_NUM_LOCK_LED),
1794 (ledstate & QEMU_SCROLL_LOCK_LED));
1796 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1797 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
1798 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
1800 if (vs->modifiers_state[0x3a] != caps) {
1801 vs->modifiers_state[0x3a] = caps;
1803 if (vs->modifiers_state[0x45] != num) {
1804 vs->modifiers_state[0x45] = num;
1806 if (vs->modifiers_state[0x46] != scr) {
1807 vs->modifiers_state[0x46] = scr;
1810 /* Sending the current led state message to the client */
1811 if (has_changed) {
1812 vnc_led_state_change(vs);
1816 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1818 /* QEMU console switch */
1819 switch(keycode) {
1820 case 0x2a: /* Left Shift */
1821 case 0x36: /* Right Shift */
1822 case 0x1d: /* Left CTRL */
1823 case 0x9d: /* Right CTRL */
1824 case 0x38: /* Left ALT */
1825 case 0xb8: /* Right ALT */
1826 if (down)
1827 vs->modifiers_state[keycode] = 1;
1828 else
1829 vs->modifiers_state[keycode] = 0;
1830 break;
1831 case 0x02 ... 0x0a: /* '1' to '9' keys */
1832 if (vs->vd->dcl.con == NULL &&
1833 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1834 /* Reset the modifiers sent to the current console */
1835 reset_keys(vs);
1836 console_select(keycode - 0x02);
1837 return;
1839 break;
1840 case 0x3a: /* CapsLock */
1841 case 0x45: /* NumLock */
1842 if (down)
1843 vs->modifiers_state[keycode] ^= 1;
1844 break;
1847 /* Turn off the lock state sync logic if the client support the led
1848 state extension.
1850 if (down && vs->vd->lock_key_sync &&
1851 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1852 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1853 /* If the numlock state needs to change then simulate an additional
1854 keypress before sending this one. This will happen if the user
1855 toggles numlock away from the VNC window.
1857 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1858 if (!vs->modifiers_state[0x45]) {
1859 trace_vnc_key_sync_numlock(true);
1860 vs->modifiers_state[0x45] = 1;
1861 press_key(vs, 0xff7f);
1863 } else {
1864 if (vs->modifiers_state[0x45]) {
1865 trace_vnc_key_sync_numlock(false);
1866 vs->modifiers_state[0x45] = 0;
1867 press_key(vs, 0xff7f);
1872 if (down && vs->vd->lock_key_sync &&
1873 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1874 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1875 /* If the capslock state needs to change then simulate an additional
1876 keypress before sending this one. This will happen if the user
1877 toggles capslock away from the VNC window.
1879 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1880 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1881 int capslock = !!(vs->modifiers_state[0x3a]);
1882 if (capslock) {
1883 if (uppercase == shift) {
1884 trace_vnc_key_sync_capslock(false);
1885 vs->modifiers_state[0x3a] = 0;
1886 press_key(vs, 0xffe5);
1888 } else {
1889 if (uppercase != shift) {
1890 trace_vnc_key_sync_capslock(true);
1891 vs->modifiers_state[0x3a] = 1;
1892 press_key(vs, 0xffe5);
1897 if (qemu_console_is_graphic(NULL)) {
1898 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
1899 } else {
1900 bool numlock = vs->modifiers_state[0x45];
1901 bool control = (vs->modifiers_state[0x1d] ||
1902 vs->modifiers_state[0x9d]);
1903 /* QEMU console emulation */
1904 if (down) {
1905 switch (keycode) {
1906 case 0x2a: /* Left Shift */
1907 case 0x36: /* Right Shift */
1908 case 0x1d: /* Left CTRL */
1909 case 0x9d: /* Right CTRL */
1910 case 0x38: /* Left ALT */
1911 case 0xb8: /* Right ALT */
1912 break;
1913 case 0xc8:
1914 kbd_put_keysym(QEMU_KEY_UP);
1915 break;
1916 case 0xd0:
1917 kbd_put_keysym(QEMU_KEY_DOWN);
1918 break;
1919 case 0xcb:
1920 kbd_put_keysym(QEMU_KEY_LEFT);
1921 break;
1922 case 0xcd:
1923 kbd_put_keysym(QEMU_KEY_RIGHT);
1924 break;
1925 case 0xd3:
1926 kbd_put_keysym(QEMU_KEY_DELETE);
1927 break;
1928 case 0xc7:
1929 kbd_put_keysym(QEMU_KEY_HOME);
1930 break;
1931 case 0xcf:
1932 kbd_put_keysym(QEMU_KEY_END);
1933 break;
1934 case 0xc9:
1935 kbd_put_keysym(QEMU_KEY_PAGEUP);
1936 break;
1937 case 0xd1:
1938 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1939 break;
1941 case 0x47:
1942 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1943 break;
1944 case 0x48:
1945 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1946 break;
1947 case 0x49:
1948 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1949 break;
1950 case 0x4b:
1951 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1952 break;
1953 case 0x4c:
1954 kbd_put_keysym('5');
1955 break;
1956 case 0x4d:
1957 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1958 break;
1959 case 0x4f:
1960 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1961 break;
1962 case 0x50:
1963 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1964 break;
1965 case 0x51:
1966 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1967 break;
1968 case 0x52:
1969 kbd_put_keysym('0');
1970 break;
1971 case 0x53:
1972 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1973 break;
1975 case 0xb5:
1976 kbd_put_keysym('/');
1977 break;
1978 case 0x37:
1979 kbd_put_keysym('*');
1980 break;
1981 case 0x4a:
1982 kbd_put_keysym('-');
1983 break;
1984 case 0x4e:
1985 kbd_put_keysym('+');
1986 break;
1987 case 0x9c:
1988 kbd_put_keysym('\n');
1989 break;
1991 default:
1992 if (control) {
1993 kbd_put_keysym(sym & 0x1f);
1994 } else {
1995 kbd_put_keysym(sym);
1997 break;
2003 static void vnc_release_modifiers(VncState *vs)
2005 static const int keycodes[] = {
2006 /* shift, control, alt keys, both left & right */
2007 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
2009 int i, keycode;
2011 if (!qemu_console_is_graphic(NULL)) {
2012 return;
2014 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
2015 keycode = keycodes[i];
2016 if (!vs->modifiers_state[keycode]) {
2017 continue;
2019 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
2023 static const char *code2name(int keycode)
2025 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
2028 static void key_event(VncState *vs, int down, uint32_t sym)
2030 int keycode;
2031 int lsym = sym;
2033 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2034 lsym = lsym - 'A' + 'a';
2037 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
2038 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2039 do_key_event(vs, down, keycode, sym);
2042 static void ext_key_event(VncState *vs, int down,
2043 uint32_t sym, uint16_t keycode)
2045 /* if the user specifies a keyboard layout, always use it */
2046 if (keyboard_layout) {
2047 key_event(vs, down, sym);
2048 } else {
2049 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2050 do_key_event(vs, down, keycode, sym);
2054 static void framebuffer_update_request(VncState *vs, int incremental,
2055 int x, int y, int w, int h)
2057 int width = pixman_image_get_width(vs->vd->server);
2058 int height = pixman_image_get_height(vs->vd->server);
2060 vs->need_update = 1;
2062 if (incremental) {
2063 return;
2066 vs->force_update = 1;
2067 vnc_set_area_dirty(vs->dirty, width, height, x, y, w, h);
2070 static void send_ext_key_event_ack(VncState *vs)
2072 vnc_lock_output(vs);
2073 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2074 vnc_write_u8(vs, 0);
2075 vnc_write_u16(vs, 1);
2076 vnc_framebuffer_update(vs, 0, 0,
2077 pixman_image_get_width(vs->vd->server),
2078 pixman_image_get_height(vs->vd->server),
2079 VNC_ENCODING_EXT_KEY_EVENT);
2080 vnc_unlock_output(vs);
2081 vnc_flush(vs);
2084 static void send_ext_audio_ack(VncState *vs)
2086 vnc_lock_output(vs);
2087 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2088 vnc_write_u8(vs, 0);
2089 vnc_write_u16(vs, 1);
2090 vnc_framebuffer_update(vs, 0, 0,
2091 pixman_image_get_width(vs->vd->server),
2092 pixman_image_get_height(vs->vd->server),
2093 VNC_ENCODING_AUDIO);
2094 vnc_unlock_output(vs);
2095 vnc_flush(vs);
2098 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2100 int i;
2101 unsigned int enc = 0;
2103 vs->features = 0;
2104 vs->vnc_encoding = 0;
2105 vs->tight.compression = 9;
2106 vs->tight.quality = -1; /* Lossless by default */
2107 vs->absolute = -1;
2110 * Start from the end because the encodings are sent in order of preference.
2111 * This way the preferred encoding (first encoding defined in the array)
2112 * will be set at the end of the loop.
2114 for (i = n_encodings - 1; i >= 0; i--) {
2115 enc = encodings[i];
2116 switch (enc) {
2117 case VNC_ENCODING_RAW:
2118 vs->vnc_encoding = enc;
2119 break;
2120 case VNC_ENCODING_COPYRECT:
2121 vs->features |= VNC_FEATURE_COPYRECT_MASK;
2122 break;
2123 case VNC_ENCODING_HEXTILE:
2124 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2125 vs->vnc_encoding = enc;
2126 break;
2127 case VNC_ENCODING_TIGHT:
2128 vs->features |= VNC_FEATURE_TIGHT_MASK;
2129 vs->vnc_encoding = enc;
2130 break;
2131 #ifdef CONFIG_VNC_PNG
2132 case VNC_ENCODING_TIGHT_PNG:
2133 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2134 vs->vnc_encoding = enc;
2135 break;
2136 #endif
2137 case VNC_ENCODING_ZLIB:
2138 vs->features |= VNC_FEATURE_ZLIB_MASK;
2139 vs->vnc_encoding = enc;
2140 break;
2141 case VNC_ENCODING_ZRLE:
2142 vs->features |= VNC_FEATURE_ZRLE_MASK;
2143 vs->vnc_encoding = enc;
2144 break;
2145 case VNC_ENCODING_ZYWRLE:
2146 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2147 vs->vnc_encoding = enc;
2148 break;
2149 case VNC_ENCODING_DESKTOPRESIZE:
2150 vs->features |= VNC_FEATURE_RESIZE_MASK;
2151 break;
2152 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2153 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2154 break;
2155 case VNC_ENCODING_RICH_CURSOR:
2156 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2157 break;
2158 case VNC_ENCODING_EXT_KEY_EVENT:
2159 send_ext_key_event_ack(vs);
2160 break;
2161 case VNC_ENCODING_AUDIO:
2162 send_ext_audio_ack(vs);
2163 break;
2164 case VNC_ENCODING_WMVi:
2165 vs->features |= VNC_FEATURE_WMVI_MASK;
2166 break;
2167 case VNC_ENCODING_LED_STATE:
2168 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2169 break;
2170 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2171 vs->tight.compression = (enc & 0x0F);
2172 break;
2173 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2174 if (vs->vd->lossy) {
2175 vs->tight.quality = (enc & 0x0F);
2177 break;
2178 default:
2179 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2180 break;
2183 vnc_desktop_resize(vs);
2184 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2185 vnc_led_state_change(vs);
2188 static void set_pixel_conversion(VncState *vs)
2190 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2192 if (fmt == VNC_SERVER_FB_FORMAT) {
2193 vs->write_pixels = vnc_write_pixels_copy;
2194 vnc_hextile_set_pixel_conversion(vs, 0);
2195 } else {
2196 vs->write_pixels = vnc_write_pixels_generic;
2197 vnc_hextile_set_pixel_conversion(vs, 1);
2201 static void set_pixel_format(VncState *vs,
2202 int bits_per_pixel, int depth,
2203 int big_endian_flag, int true_color_flag,
2204 int red_max, int green_max, int blue_max,
2205 int red_shift, int green_shift, int blue_shift)
2207 if (!true_color_flag) {
2208 vnc_client_error(vs);
2209 return;
2212 switch (bits_per_pixel) {
2213 case 8:
2214 case 16:
2215 case 32:
2216 break;
2217 default:
2218 vnc_client_error(vs);
2219 return;
2222 vs->client_pf.rmax = red_max;
2223 vs->client_pf.rbits = hweight_long(red_max);
2224 vs->client_pf.rshift = red_shift;
2225 vs->client_pf.rmask = red_max << red_shift;
2226 vs->client_pf.gmax = green_max;
2227 vs->client_pf.gbits = hweight_long(green_max);
2228 vs->client_pf.gshift = green_shift;
2229 vs->client_pf.gmask = green_max << green_shift;
2230 vs->client_pf.bmax = blue_max;
2231 vs->client_pf.bbits = hweight_long(blue_max);
2232 vs->client_pf.bshift = blue_shift;
2233 vs->client_pf.bmask = blue_max << blue_shift;
2234 vs->client_pf.bits_per_pixel = bits_per_pixel;
2235 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2236 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2237 vs->client_be = big_endian_flag;
2239 set_pixel_conversion(vs);
2241 graphic_hw_invalidate(vs->vd->dcl.con);
2242 graphic_hw_update(vs->vd->dcl.con);
2245 static void pixel_format_message (VncState *vs) {
2246 char pad[3] = { 0, 0, 0 };
2248 vs->client_pf = qemu_default_pixelformat(32);
2250 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2251 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
2253 #ifdef HOST_WORDS_BIGENDIAN
2254 vnc_write_u8(vs, 1); /* big-endian-flag */
2255 #else
2256 vnc_write_u8(vs, 0); /* big-endian-flag */
2257 #endif
2258 vnc_write_u8(vs, 1); /* true-color-flag */
2259 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2260 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2261 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2262 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2263 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2264 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2265 vnc_write(vs, pad, 3); /* padding */
2267 vnc_hextile_set_pixel_conversion(vs, 0);
2268 vs->write_pixels = vnc_write_pixels_copy;
2271 static void vnc_colordepth(VncState *vs)
2273 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2274 /* Sending a WMVi message to notify the client*/
2275 vnc_lock_output(vs);
2276 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2277 vnc_write_u8(vs, 0);
2278 vnc_write_u16(vs, 1); /* number of rects */
2279 vnc_framebuffer_update(vs, 0, 0,
2280 pixman_image_get_width(vs->vd->server),
2281 pixman_image_get_height(vs->vd->server),
2282 VNC_ENCODING_WMVi);
2283 pixel_format_message(vs);
2284 vnc_unlock_output(vs);
2285 vnc_flush(vs);
2286 } else {
2287 set_pixel_conversion(vs);
2291 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2293 int i;
2294 uint16_t limit;
2295 VncDisplay *vd = vs->vd;
2297 if (data[0] > 3) {
2298 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2301 switch (data[0]) {
2302 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2303 if (len == 1)
2304 return 20;
2306 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2307 read_u8(data, 6), read_u8(data, 7),
2308 read_u16(data, 8), read_u16(data, 10),
2309 read_u16(data, 12), read_u8(data, 14),
2310 read_u8(data, 15), read_u8(data, 16));
2311 break;
2312 case VNC_MSG_CLIENT_SET_ENCODINGS:
2313 if (len == 1)
2314 return 4;
2316 if (len == 4) {
2317 limit = read_u16(data, 2);
2318 if (limit > 0)
2319 return 4 + (limit * 4);
2320 } else
2321 limit = read_u16(data, 2);
2323 for (i = 0; i < limit; i++) {
2324 int32_t val = read_s32(data, 4 + (i * 4));
2325 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2328 set_encodings(vs, (int32_t *)(data + 4), limit);
2329 break;
2330 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2331 if (len == 1)
2332 return 10;
2334 framebuffer_update_request(vs,
2335 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2336 read_u16(data, 6), read_u16(data, 8));
2337 break;
2338 case VNC_MSG_CLIENT_KEY_EVENT:
2339 if (len == 1)
2340 return 8;
2342 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2343 break;
2344 case VNC_MSG_CLIENT_POINTER_EVENT:
2345 if (len == 1)
2346 return 6;
2348 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2349 break;
2350 case VNC_MSG_CLIENT_CUT_TEXT:
2351 if (len == 1) {
2352 return 8;
2354 if (len == 8) {
2355 uint32_t dlen = read_u32(data, 4);
2356 if (dlen > (1 << 20)) {
2357 error_report("vnc: client_cut_text msg payload has %u bytes"
2358 " which exceeds our limit of 1MB.", dlen);
2359 vnc_client_error(vs);
2360 break;
2362 if (dlen > 0) {
2363 return 8 + dlen;
2367 client_cut_text(vs, read_u32(data, 4), data + 8);
2368 break;
2369 case VNC_MSG_CLIENT_QEMU:
2370 if (len == 1)
2371 return 2;
2373 switch (read_u8(data, 1)) {
2374 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2375 if (len == 2)
2376 return 12;
2378 ext_key_event(vs, read_u16(data, 2),
2379 read_u32(data, 4), read_u32(data, 8));
2380 break;
2381 case VNC_MSG_CLIENT_QEMU_AUDIO:
2382 if (len == 2)
2383 return 4;
2385 switch (read_u16 (data, 2)) {
2386 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2387 audio_add(vs);
2388 break;
2389 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2390 audio_del(vs);
2391 break;
2392 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2393 if (len == 4)
2394 return 10;
2395 switch (read_u8(data, 4)) {
2396 case 0: vs->as.fmt = AUD_FMT_U8; break;
2397 case 1: vs->as.fmt = AUD_FMT_S8; break;
2398 case 2: vs->as.fmt = AUD_FMT_U16; break;
2399 case 3: vs->as.fmt = AUD_FMT_S16; break;
2400 case 4: vs->as.fmt = AUD_FMT_U32; break;
2401 case 5: vs->as.fmt = AUD_FMT_S32; break;
2402 default:
2403 printf("Invalid audio format %d\n", read_u8(data, 4));
2404 vnc_client_error(vs);
2405 break;
2407 vs->as.nchannels = read_u8(data, 5);
2408 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2409 printf("Invalid audio channel coount %d\n",
2410 read_u8(data, 5));
2411 vnc_client_error(vs);
2412 break;
2414 vs->as.freq = read_u32(data, 6);
2415 break;
2416 default:
2417 printf ("Invalid audio message %d\n", read_u8(data, 4));
2418 vnc_client_error(vs);
2419 break;
2421 break;
2423 default:
2424 printf("Msg: %d\n", read_u16(data, 0));
2425 vnc_client_error(vs);
2426 break;
2428 break;
2429 default:
2430 printf("Msg: %d\n", data[0]);
2431 vnc_client_error(vs);
2432 break;
2435 vnc_read_when(vs, protocol_client_msg, 1);
2436 return 0;
2439 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2441 char buf[1024];
2442 VncShareMode mode;
2443 int size;
2445 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2446 switch (vs->vd->share_policy) {
2447 case VNC_SHARE_POLICY_IGNORE:
2449 * Ignore the shared flag. Nothing to do here.
2451 * Doesn't conform to the rfb spec but is traditional qemu
2452 * behavior, thus left here as option for compatibility
2453 * reasons.
2455 break;
2456 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2458 * Policy: Allow clients ask for exclusive access.
2460 * Implementation: When a client asks for exclusive access,
2461 * disconnect all others. Shared connects are allowed as long
2462 * as no exclusive connection exists.
2464 * This is how the rfb spec suggests to handle the shared flag.
2466 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2467 VncState *client;
2468 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2469 if (vs == client) {
2470 continue;
2472 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2473 client->share_mode != VNC_SHARE_MODE_SHARED) {
2474 continue;
2476 vnc_disconnect_start(client);
2479 if (mode == VNC_SHARE_MODE_SHARED) {
2480 if (vs->vd->num_exclusive > 0) {
2481 vnc_disconnect_start(vs);
2482 return 0;
2485 break;
2486 case VNC_SHARE_POLICY_FORCE_SHARED:
2488 * Policy: Shared connects only.
2489 * Implementation: Disallow clients asking for exclusive access.
2491 * Useful for shared desktop sessions where you don't want
2492 * someone forgetting to say -shared when running the vnc
2493 * client disconnect everybody else.
2495 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2496 vnc_disconnect_start(vs);
2497 return 0;
2499 break;
2501 vnc_set_share_mode(vs, mode);
2503 if (vs->vd->num_shared > vs->vd->connections_limit) {
2504 vnc_disconnect_start(vs);
2505 return 0;
2508 vs->client_width = pixman_image_get_width(vs->vd->server);
2509 vs->client_height = pixman_image_get_height(vs->vd->server);
2510 vnc_write_u16(vs, vs->client_width);
2511 vnc_write_u16(vs, vs->client_height);
2513 pixel_format_message(vs);
2515 if (qemu_name)
2516 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2517 else
2518 size = snprintf(buf, sizeof(buf), "QEMU");
2520 vnc_write_u32(vs, size);
2521 vnc_write(vs, buf, size);
2522 vnc_flush(vs);
2524 vnc_client_cache_auth(vs);
2525 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2527 vnc_read_when(vs, protocol_client_msg, 1);
2529 return 0;
2532 void start_client_init(VncState *vs)
2534 vnc_read_when(vs, protocol_client_init, 1);
2537 static void make_challenge(VncState *vs)
2539 int i;
2541 srand(time(NULL)+getpid()+getpid()*987654+rand());
2543 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2544 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2547 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2549 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2550 int i, j, pwlen;
2551 unsigned char key[8];
2552 time_t now = time(NULL);
2554 if (!vs->vd->password) {
2555 VNC_DEBUG("No password configured on server");
2556 goto reject;
2558 if (vs->vd->expires < now) {
2559 VNC_DEBUG("Password is expired");
2560 goto reject;
2563 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2565 /* Calculate the expected challenge response */
2566 pwlen = strlen(vs->vd->password);
2567 for (i=0; i<sizeof(key); i++)
2568 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2569 deskey(key, EN0);
2570 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
2571 des(response+j, response+j);
2573 /* Compare expected vs actual challenge response */
2574 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2575 VNC_DEBUG("Client challenge response did not match\n");
2576 goto reject;
2577 } else {
2578 VNC_DEBUG("Accepting VNC challenge response\n");
2579 vnc_write_u32(vs, 0); /* Accept auth */
2580 vnc_flush(vs);
2582 start_client_init(vs);
2584 return 0;
2586 reject:
2587 vnc_write_u32(vs, 1); /* Reject auth */
2588 if (vs->minor >= 8) {
2589 static const char err[] = "Authentication failed";
2590 vnc_write_u32(vs, sizeof(err));
2591 vnc_write(vs, err, sizeof(err));
2593 vnc_flush(vs);
2594 vnc_client_error(vs);
2595 return 0;
2598 void start_auth_vnc(VncState *vs)
2600 make_challenge(vs);
2601 /* Send client a 'random' challenge */
2602 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2603 vnc_flush(vs);
2605 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2609 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2611 /* We only advertise 1 auth scheme at a time, so client
2612 * must pick the one we sent. Verify this */
2613 if (data[0] != vs->auth) { /* Reject auth */
2614 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
2615 vnc_write_u32(vs, 1);
2616 if (vs->minor >= 8) {
2617 static const char err[] = "Authentication failed";
2618 vnc_write_u32(vs, sizeof(err));
2619 vnc_write(vs, err, sizeof(err));
2621 vnc_client_error(vs);
2622 } else { /* Accept requested auth */
2623 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2624 switch (vs->auth) {
2625 case VNC_AUTH_NONE:
2626 VNC_DEBUG("Accept auth none\n");
2627 if (vs->minor >= 8) {
2628 vnc_write_u32(vs, 0); /* Accept auth completion */
2629 vnc_flush(vs);
2631 start_client_init(vs);
2632 break;
2634 case VNC_AUTH_VNC:
2635 VNC_DEBUG("Start VNC auth\n");
2636 start_auth_vnc(vs);
2637 break;
2639 #ifdef CONFIG_VNC_TLS
2640 case VNC_AUTH_VENCRYPT:
2641 VNC_DEBUG("Accept VeNCrypt auth\n");
2642 start_auth_vencrypt(vs);
2643 break;
2644 #endif /* CONFIG_VNC_TLS */
2646 #ifdef CONFIG_VNC_SASL
2647 case VNC_AUTH_SASL:
2648 VNC_DEBUG("Accept SASL auth\n");
2649 start_auth_sasl(vs);
2650 break;
2651 #endif /* CONFIG_VNC_SASL */
2653 default: /* Should not be possible, but just in case */
2654 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
2655 vnc_write_u8(vs, 1);
2656 if (vs->minor >= 8) {
2657 static const char err[] = "Authentication failed";
2658 vnc_write_u32(vs, sizeof(err));
2659 vnc_write(vs, err, sizeof(err));
2661 vnc_client_error(vs);
2664 return 0;
2667 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2669 char local[13];
2671 memcpy(local, version, 12);
2672 local[12] = 0;
2674 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2675 VNC_DEBUG("Malformed protocol version %s\n", local);
2676 vnc_client_error(vs);
2677 return 0;
2679 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2680 if (vs->major != 3 ||
2681 (vs->minor != 3 &&
2682 vs->minor != 4 &&
2683 vs->minor != 5 &&
2684 vs->minor != 7 &&
2685 vs->minor != 8)) {
2686 VNC_DEBUG("Unsupported client version\n");
2687 vnc_write_u32(vs, VNC_AUTH_INVALID);
2688 vnc_flush(vs);
2689 vnc_client_error(vs);
2690 return 0;
2692 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2693 * as equivalent to v3.3 by servers
2695 if (vs->minor == 4 || vs->minor == 5)
2696 vs->minor = 3;
2698 if (vs->minor == 3) {
2699 if (vs->auth == VNC_AUTH_NONE) {
2700 VNC_DEBUG("Tell client auth none\n");
2701 vnc_write_u32(vs, vs->auth);
2702 vnc_flush(vs);
2703 start_client_init(vs);
2704 } else if (vs->auth == VNC_AUTH_VNC) {
2705 VNC_DEBUG("Tell client VNC auth\n");
2706 vnc_write_u32(vs, vs->auth);
2707 vnc_flush(vs);
2708 start_auth_vnc(vs);
2709 } else {
2710 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2711 vnc_write_u32(vs, VNC_AUTH_INVALID);
2712 vnc_flush(vs);
2713 vnc_client_error(vs);
2715 } else {
2716 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2717 vnc_write_u8(vs, 1); /* num auth */
2718 vnc_write_u8(vs, vs->auth);
2719 vnc_read_when(vs, protocol_client_auth, 1);
2720 vnc_flush(vs);
2723 return 0;
2726 static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2728 struct VncSurface *vs = &vd->guest;
2730 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2733 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2735 int i, j;
2737 w = (x + w) / VNC_STAT_RECT;
2738 h = (y + h) / VNC_STAT_RECT;
2739 x /= VNC_STAT_RECT;
2740 y /= VNC_STAT_RECT;
2742 for (j = y; j <= h; j++) {
2743 for (i = x; i <= w; i++) {
2744 vs->lossy_rect[j][i] = 1;
2749 static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2751 VncState *vs;
2752 int sty = y / VNC_STAT_RECT;
2753 int stx = x / VNC_STAT_RECT;
2754 int has_dirty = 0;
2756 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2757 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2759 QTAILQ_FOREACH(vs, &vd->clients, next) {
2760 int j;
2762 /* kernel send buffers are full -> refresh later */
2763 if (vs->output.offset) {
2764 continue;
2767 if (!vs->lossy_rect[sty][stx]) {
2768 continue;
2771 vs->lossy_rect[sty][stx] = 0;
2772 for (j = 0; j < VNC_STAT_RECT; ++j) {
2773 bitmap_set(vs->dirty[y + j],
2774 x / VNC_DIRTY_PIXELS_PER_BIT,
2775 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2777 has_dirty++;
2780 return has_dirty;
2783 static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2785 int width = pixman_image_get_width(vd->guest.fb);
2786 int height = pixman_image_get_height(vd->guest.fb);
2787 int x, y;
2788 struct timeval res;
2789 int has_dirty = 0;
2791 for (y = 0; y < height; y += VNC_STAT_RECT) {
2792 for (x = 0; x < width; x += VNC_STAT_RECT) {
2793 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2795 rect->updated = false;
2799 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2801 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2802 return has_dirty;
2804 vd->guest.last_freq_check = *tv;
2806 for (y = 0; y < height; y += VNC_STAT_RECT) {
2807 for (x = 0; x < width; x += VNC_STAT_RECT) {
2808 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2809 int count = ARRAY_SIZE(rect->times);
2810 struct timeval min, max;
2812 if (!timerisset(&rect->times[count - 1])) {
2813 continue ;
2816 max = rect->times[(rect->idx + count - 1) % count];
2817 qemu_timersub(tv, &max, &res);
2819 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2820 rect->freq = 0;
2821 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
2822 memset(rect->times, 0, sizeof (rect->times));
2823 continue ;
2826 min = rect->times[rect->idx];
2827 max = rect->times[(rect->idx + count - 1) % count];
2828 qemu_timersub(&max, &min, &res);
2830 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2831 rect->freq /= count;
2832 rect->freq = 1. / rect->freq;
2835 return has_dirty;
2838 double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2840 int i, j;
2841 double total = 0;
2842 int num = 0;
2844 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2845 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2847 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2848 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2849 total += vnc_stat_rect(vs->vd, i, j)->freq;
2850 num++;
2854 if (num) {
2855 return total / num;
2856 } else {
2857 return 0;
2861 static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2863 VncRectStat *rect;
2865 rect = vnc_stat_rect(vd, x, y);
2866 if (rect->updated) {
2867 return ;
2869 rect->times[rect->idx] = *tv;
2870 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2871 rect->updated = true;
2874 static int vnc_refresh_server_surface(VncDisplay *vd)
2876 int width = MIN(pixman_image_get_width(vd->guest.fb),
2877 pixman_image_get_width(vd->server));
2878 int height = MIN(pixman_image_get_height(vd->guest.fb),
2879 pixman_image_get_height(vd->server));
2880 int cmp_bytes, server_stride, min_stride, guest_stride, y = 0;
2881 uint8_t *guest_row0 = NULL, *server_row0;
2882 VncState *vs;
2883 int has_dirty = 0;
2884 pixman_image_t *tmpbuf = NULL;
2886 struct timeval tv = { 0, 0 };
2888 if (!vd->non_adaptive) {
2889 gettimeofday(&tv, NULL);
2890 has_dirty = vnc_update_stats(vd, &tv);
2894 * Walk through the guest dirty map.
2895 * Check and copy modified bits from guest to server surface.
2896 * Update server dirty map.
2898 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2899 server_stride = guest_stride = pixman_image_get_stride(vd->server);
2900 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2901 server_stride);
2902 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2903 int width = pixman_image_get_width(vd->server);
2904 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
2905 } else {
2906 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2907 guest_stride = pixman_image_get_stride(vd->guest.fb);
2909 min_stride = MIN(server_stride, guest_stride);
2911 for (;;) {
2912 int x;
2913 uint8_t *guest_ptr, *server_ptr;
2914 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2915 height * VNC_DIRTY_BPL(&vd->guest),
2916 y * VNC_DIRTY_BPL(&vd->guest));
2917 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2918 /* no more dirty bits */
2919 break;
2921 y = offset / VNC_DIRTY_BPL(&vd->guest);
2922 x = offset % VNC_DIRTY_BPL(&vd->guest);
2924 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2926 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2927 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2928 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2929 } else {
2930 guest_ptr = guest_row0 + y * guest_stride;
2932 guest_ptr += x * cmp_bytes;
2934 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2935 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2936 int _cmp_bytes = cmp_bytes;
2937 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2938 continue;
2940 if ((x + 1) * cmp_bytes > min_stride) {
2941 _cmp_bytes = min_stride - x * cmp_bytes;
2943 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
2944 continue;
2946 memcpy(server_ptr, guest_ptr, _cmp_bytes);
2947 if (!vd->non_adaptive) {
2948 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2949 y, &tv);
2951 QTAILQ_FOREACH(vs, &vd->clients, next) {
2952 set_bit(x, vs->dirty[y]);
2954 has_dirty++;
2957 y++;
2959 qemu_pixman_image_unref(tmpbuf);
2960 return has_dirty;
2963 static void vnc_refresh(DisplayChangeListener *dcl)
2965 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
2966 VncState *vs, *vn;
2967 int has_dirty, rects = 0;
2969 if (QTAILQ_EMPTY(&vd->clients)) {
2970 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2971 return;
2974 graphic_hw_update(vd->dcl.con);
2976 if (vnc_trylock_display(vd)) {
2977 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2978 return;
2981 has_dirty = vnc_refresh_server_surface(vd);
2982 vnc_unlock_display(vd);
2984 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
2985 rects += vnc_update_client(vs, has_dirty, false);
2986 /* vs might be free()ed here */
2989 if (has_dirty && rects) {
2990 vd->dcl.update_interval /= 2;
2991 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2992 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2994 } else {
2995 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2996 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2997 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3002 static void vnc_connect(VncDisplay *vd, int csock,
3003 bool skipauth, bool websocket)
3005 VncState *vs = g_malloc0(sizeof(VncState));
3006 int i;
3008 vs->csock = csock;
3009 vs->vd = vd;
3011 if (skipauth) {
3012 vs->auth = VNC_AUTH_NONE;
3013 #ifdef CONFIG_VNC_TLS
3014 vs->subauth = VNC_AUTH_INVALID;
3015 #endif
3016 } else {
3017 vs->auth = vd->auth;
3018 #ifdef CONFIG_VNC_TLS
3019 vs->subauth = vd->subauth;
3020 #endif
3023 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3024 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3025 vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));
3028 VNC_DEBUG("New client on socket %d\n", csock);
3029 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3030 qemu_set_nonblock(vs->csock);
3031 #ifdef CONFIG_VNC_WS
3032 if (websocket) {
3033 vs->websocket = 1;
3034 #ifdef CONFIG_VNC_TLS
3035 if (vd->tls.x509cert) {
3036 qemu_set_fd_handler2(vs->csock, NULL, vncws_tls_handshake_peek,
3037 NULL, vs);
3038 } else
3039 #endif /* CONFIG_VNC_TLS */
3041 qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read,
3042 NULL, vs);
3044 } else
3045 #endif /* CONFIG_VNC_WS */
3047 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
3050 vnc_client_cache_addr(vs);
3051 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3052 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3054 #ifdef CONFIG_VNC_WS
3055 if (!vs->websocket)
3056 #endif
3058 vnc_init_state(vs);
3061 if (vd->num_connecting > vd->connections_limit) {
3062 QTAILQ_FOREACH(vs, &vd->clients, next) {
3063 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3064 vnc_disconnect_start(vs);
3065 return;
3071 void vnc_init_state(VncState *vs)
3073 vs->initialized = true;
3074 VncDisplay *vd = vs->vd;
3076 vs->last_x = -1;
3077 vs->last_y = -1;
3079 vs->as.freq = 44100;
3080 vs->as.nchannels = 2;
3081 vs->as.fmt = AUD_FMT_S16;
3082 vs->as.endianness = 0;
3084 qemu_mutex_init(&vs->output_mutex);
3085 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3087 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3089 graphic_hw_update(vd->dcl.con);
3091 vnc_write(vs, "RFB 003.008\n", 12);
3092 vnc_flush(vs);
3093 vnc_read_when(vs, protocol_version, 12);
3094 reset_keys(vs);
3095 if (vs->vd->lock_key_sync)
3096 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
3098 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3099 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3101 /* vs might be free()ed here */
3104 static void vnc_listen_read(void *opaque, bool websocket)
3106 VncDisplay *vs = opaque;
3107 struct sockaddr_in addr;
3108 socklen_t addrlen = sizeof(addr);
3109 int csock;
3111 /* Catch-up */
3112 graphic_hw_update(vs->dcl.con);
3113 #ifdef CONFIG_VNC_WS
3114 if (websocket) {
3115 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
3116 } else
3117 #endif /* CONFIG_VNC_WS */
3119 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
3122 if (csock != -1) {
3123 socket_set_nodelay(csock);
3124 vnc_connect(vs, csock, false, websocket);
3128 static void vnc_listen_regular_read(void *opaque)
3130 vnc_listen_read(opaque, false);
3133 #ifdef CONFIG_VNC_WS
3134 static void vnc_listen_websocket_read(void *opaque)
3136 vnc_listen_read(opaque, true);
3138 #endif /* CONFIG_VNC_WS */
3140 static const DisplayChangeListenerOps dcl_ops = {
3141 .dpy_name = "vnc",
3142 .dpy_refresh = vnc_refresh,
3143 .dpy_gfx_copy = vnc_dpy_copy,
3144 .dpy_gfx_update = vnc_dpy_update,
3145 .dpy_gfx_switch = vnc_dpy_switch,
3146 .dpy_gfx_check_format = qemu_pixman_check_format,
3147 .dpy_mouse_set = vnc_mouse_set,
3148 .dpy_cursor_define = vnc_dpy_cursor_define,
3151 void vnc_display_init(const char *id)
3153 VncDisplay *vs;
3155 if (vnc_display_find(id) != NULL) {
3156 return;
3158 vs = g_malloc0(sizeof(*vs));
3160 vs->id = strdup(id);
3161 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
3163 vs->lsock = -1;
3164 #ifdef CONFIG_VNC_WS
3165 vs->lwebsock = -1;
3166 #endif
3168 QTAILQ_INIT(&vs->clients);
3169 vs->expires = TIME_MAX;
3171 if (keyboard_layout) {
3172 trace_vnc_key_map_init(keyboard_layout);
3173 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
3174 } else {
3175 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
3178 if (!vs->kbd_layout)
3179 exit(1);
3181 qemu_mutex_init(&vs->mutex);
3182 vnc_start_worker_thread();
3184 vs->dcl.ops = &dcl_ops;
3185 register_displaychangelistener(&vs->dcl);
3189 static void vnc_display_close(VncDisplay *vs)
3191 if (!vs)
3192 return;
3193 g_free(vs->display);
3194 vs->display = NULL;
3195 if (vs->lsock != -1) {
3196 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
3197 close(vs->lsock);
3198 vs->lsock = -1;
3200 #ifdef CONFIG_VNC_WS
3201 g_free(vs->ws_display);
3202 vs->ws_display = NULL;
3203 if (vs->lwebsock != -1) {
3204 qemu_set_fd_handler2(vs->lwebsock, NULL, NULL, NULL, NULL);
3205 close(vs->lwebsock);
3206 vs->lwebsock = -1;
3208 #endif /* CONFIG_VNC_WS */
3209 vs->auth = VNC_AUTH_INVALID;
3210 #ifdef CONFIG_VNC_TLS
3211 vs->subauth = VNC_AUTH_INVALID;
3212 vs->tls.x509verify = 0;
3213 #endif
3216 int vnc_display_password(const char *id, const char *password)
3218 VncDisplay *vs = vnc_display_find(id);
3220 if (!vs) {
3221 return -EINVAL;
3223 if (vs->auth == VNC_AUTH_NONE) {
3224 error_printf_unless_qmp("If you want use passwords please enable "
3225 "password auth using '-vnc ${dpy},password'.");
3226 return -EINVAL;
3229 g_free(vs->password);
3230 vs->password = g_strdup(password);
3232 return 0;
3235 int vnc_display_pw_expire(const char *id, time_t expires)
3237 VncDisplay *vs = vnc_display_find(id);
3239 if (!vs) {
3240 return -EINVAL;
3243 vs->expires = expires;
3244 return 0;
3247 char *vnc_display_local_addr(const char *id)
3249 VncDisplay *vs = vnc_display_find(id);
3251 assert(vs);
3252 return vnc_socket_local_addr("%s:%s", vs->lsock);
3255 static QemuOptsList qemu_vnc_opts = {
3256 .name = "vnc",
3257 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3258 .implied_opt_name = "vnc",
3259 .desc = {
3261 .name = "vnc",
3262 .type = QEMU_OPT_STRING,
3264 .name = "websocket",
3265 .type = QEMU_OPT_STRING,
3267 .name = "x509",
3268 .type = QEMU_OPT_STRING,
3270 .name = "share",
3271 .type = QEMU_OPT_STRING,
3273 .name = "display",
3274 .type = QEMU_OPT_STRING,
3276 .name = "head",
3277 .type = QEMU_OPT_NUMBER,
3279 .name = "connections",
3280 .type = QEMU_OPT_NUMBER,
3282 .name = "to",
3283 .type = QEMU_OPT_NUMBER,
3285 .name = "ipv4",
3286 .type = QEMU_OPT_BOOL,
3288 .name = "ipv6",
3289 .type = QEMU_OPT_BOOL,
3291 .name = "password",
3292 .type = QEMU_OPT_BOOL,
3294 .name = "reverse",
3295 .type = QEMU_OPT_BOOL,
3297 .name = "lock-key-sync",
3298 .type = QEMU_OPT_BOOL,
3300 .name = "sasl",
3301 .type = QEMU_OPT_BOOL,
3303 .name = "tls",
3304 .type = QEMU_OPT_BOOL,
3306 .name = "x509verify",
3307 .type = QEMU_OPT_BOOL,
3309 .name = "acl",
3310 .type = QEMU_OPT_BOOL,
3312 .name = "lossy",
3313 .type = QEMU_OPT_BOOL,
3315 .name = "non-adaptive",
3316 .type = QEMU_OPT_BOOL,
3318 { /* end of list */ }
3322 void vnc_display_open(const char *id, Error **errp)
3324 VncDisplay *vs = vnc_display_find(id);
3325 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3326 const char *share, *device_id;
3327 QemuConsole *con;
3328 bool password = false;
3329 bool reverse = false;
3330 const char *vnc;
3331 const char *has_to;
3332 char *display, *to = NULL;
3333 bool has_ipv4 = false;
3334 bool has_ipv6 = false;
3335 #ifdef CONFIG_VNC_WS
3336 const char *websocket;
3337 #endif
3338 #ifdef CONFIG_VNC_TLS
3339 bool tls = false, x509 = false;
3340 const char *path;
3341 #endif
3342 #ifdef CONFIG_VNC_SASL
3343 bool sasl = false;
3344 int saslErr;
3345 #endif
3346 #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
3347 int acl = 0;
3348 #endif
3349 int lock_key_sync = 1;
3351 if (!vs) {
3352 error_setg(errp, "VNC display not active");
3353 return;
3355 vnc_display_close(vs);
3357 if (!opts) {
3358 return;
3360 vnc = qemu_opt_get(opts, "vnc");
3361 if (!vnc || strcmp(vnc, "none") == 0) {
3362 return;
3365 has_to = qemu_opt_get(opts, "to");
3366 if (has_to) {
3367 to = g_strdup_printf(",to=%s", has_to);
3369 has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3370 has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3371 display = g_strdup_printf("%s%s%s%s", vnc,
3372 has_to ? to : "",
3373 has_ipv4 ? ",ipv4" : "",
3374 has_ipv6 ? ",ipv6" : "");
3375 vs->display = g_strdup(display);
3377 password = qemu_opt_get_bool(opts, "password", false);
3378 if (password && fips_get_state()) {
3379 error_setg(errp,
3380 "VNC password auth disabled due to FIPS mode, "
3381 "consider using the VeNCrypt or SASL authentication "
3382 "methods as an alternative");
3383 goto fail;
3386 reverse = qemu_opt_get_bool(opts, "reverse", false);
3387 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
3388 #ifdef CONFIG_VNC_SASL
3389 sasl = qemu_opt_get_bool(opts, "sasl", false);
3390 #endif
3391 #ifdef CONFIG_VNC_TLS
3392 tls = qemu_opt_get_bool(opts, "tls", false);
3393 path = qemu_opt_get(opts, "x509");
3394 if (path) {
3395 x509 = true;
3396 vs->tls.x509verify = qemu_opt_get_bool(opts, "x509verify", false);
3397 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
3398 error_setg(errp, "Failed to find x509 certificates/keys in %s",
3399 path);
3400 goto fail;
3403 #endif
3404 #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
3405 acl = qemu_opt_get_bool(opts, "acl", false);
3406 #endif
3408 share = qemu_opt_get(opts, "share");
3409 if (share) {
3410 if (strcmp(share, "ignore") == 0) {
3411 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3412 } else if (strcmp(share, "allow-exclusive") == 0) {
3413 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3414 } else if (strcmp(share, "force-shared") == 0) {
3415 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3416 } else {
3417 error_setg(errp, "unknown vnc share= option");
3418 goto fail;
3420 } else {
3421 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3423 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
3425 #ifdef CONFIG_VNC_WS
3426 websocket = qemu_opt_get(opts, "websocket");
3427 if (websocket) {
3428 /* extract the host specification from display */
3429 char *host = NULL, *host_end = NULL;
3430 vs->websocket = 1;
3432 /* ipv6 hosts have colons */
3433 host_end = strrchr(display, ':');
3434 if (host_end) {
3435 host = g_strndup(display, host_end - display + 1);
3436 } else {
3437 host = g_strdup(":");
3439 vs->ws_display = g_strconcat(host, websocket, NULL);
3440 g_free(host);
3442 #endif /* CONFIG_VNC_WS */
3444 #ifdef CONFIG_VNC_JPEG
3445 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3446 #endif
3447 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
3448 /* adaptive updates are only used with tight encoding and
3449 * if lossy updates are enabled so we can disable all the
3450 * calculations otherwise */
3451 if (!vs->lossy) {
3452 vs->non_adaptive = true;
3455 #ifdef CONFIG_VNC_TLS
3456 if (acl && x509 && vs->tls.x509verify) {
3457 char *aclname;
3459 if (strcmp(vs->id, "default") == 0) {
3460 aclname = g_strdup("vnc.x509dname");
3461 } else {
3462 aclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3464 vs->tls.acl = qemu_acl_init(aclname);
3465 if (!vs->tls.acl) {
3466 fprintf(stderr, "Failed to create x509 dname ACL\n");
3467 exit(1);
3469 g_free(aclname);
3471 #endif
3472 #ifdef CONFIG_VNC_SASL
3473 if (acl && sasl) {
3474 char *aclname;
3476 if (strcmp(vs->id, "default") == 0) {
3477 aclname = g_strdup("vnc.username");
3478 } else {
3479 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3481 vs->sasl.acl = qemu_acl_init(aclname);
3482 if (!vs->sasl.acl) {
3483 fprintf(stderr, "Failed to create username ACL\n");
3484 exit(1);
3486 g_free(aclname);
3488 #endif
3491 * Combinations we support here:
3493 * - no-auth (clear text, no auth)
3494 * - password (clear text, weak auth)
3495 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
3496 * - tls (encrypt, weak anonymous creds, no auth)
3497 * - tls + password (encrypt, weak anonymous creds, weak auth)
3498 * - tls + sasl (encrypt, weak anonymous creds, good auth)
3499 * - tls + x509 (encrypt, good x509 creds, no auth)
3500 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
3501 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
3503 * NB1. TLS is a stackable auth scheme.
3504 * NB2. the x509 schemes have option to validate a client cert dname
3506 if (password) {
3507 #ifdef CONFIG_VNC_TLS
3508 if (tls) {
3509 vs->auth = VNC_AUTH_VENCRYPT;
3510 if (x509) {
3511 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3512 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3513 } else {
3514 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3515 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3517 } else {
3518 #endif /* CONFIG_VNC_TLS */
3519 VNC_DEBUG("Initializing VNC server with password auth\n");
3520 vs->auth = VNC_AUTH_VNC;
3521 #ifdef CONFIG_VNC_TLS
3522 vs->subauth = VNC_AUTH_INVALID;
3524 #endif /* CONFIG_VNC_TLS */
3525 #ifdef CONFIG_VNC_SASL
3526 } else if (sasl) {
3527 #ifdef CONFIG_VNC_TLS
3528 if (tls) {
3529 vs->auth = VNC_AUTH_VENCRYPT;
3530 if (x509) {
3531 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3532 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3533 } else {
3534 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3535 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3537 } else {
3538 #endif /* CONFIG_VNC_TLS */
3539 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3540 vs->auth = VNC_AUTH_SASL;
3541 #ifdef CONFIG_VNC_TLS
3542 vs->subauth = VNC_AUTH_INVALID;
3544 #endif /* CONFIG_VNC_TLS */
3545 #endif /* CONFIG_VNC_SASL */
3546 } else {
3547 #ifdef CONFIG_VNC_TLS
3548 if (tls) {
3549 vs->auth = VNC_AUTH_VENCRYPT;
3550 if (x509) {
3551 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3552 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3553 } else {
3554 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3555 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3557 } else {
3558 #endif
3559 VNC_DEBUG("Initializing VNC server with no auth\n");
3560 vs->auth = VNC_AUTH_NONE;
3561 #ifdef CONFIG_VNC_TLS
3562 vs->subauth = VNC_AUTH_INVALID;
3564 #endif
3567 #ifdef CONFIG_VNC_SASL
3568 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
3569 error_setg(errp, "Failed to initialize SASL auth: %s",
3570 sasl_errstring(saslErr, NULL, NULL));
3571 goto fail;
3573 #endif
3574 vs->lock_key_sync = lock_key_sync;
3576 device_id = qemu_opt_get(opts, "display");
3577 if (device_id) {
3578 DeviceState *dev;
3579 int head = qemu_opt_get_number(opts, "head", 0);
3581 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3582 if (dev == NULL) {
3583 error_set(errp, QERR_DEVICE_NOT_FOUND, device_id);
3584 goto fail;
3587 con = qemu_console_lookup_by_device(dev, head);
3588 if (con == NULL) {
3589 error_setg(errp, "Device %s is not bound to a QemuConsole",
3590 device_id);
3591 goto fail;
3593 } else {
3594 con = NULL;
3597 if (con != vs->dcl.con) {
3598 unregister_displaychangelistener(&vs->dcl);
3599 vs->dcl.con = con;
3600 register_displaychangelistener(&vs->dcl);
3603 if (reverse) {
3604 /* connect to viewer */
3605 int csock;
3606 vs->lsock = -1;
3607 #ifdef CONFIG_VNC_WS
3608 vs->lwebsock = -1;
3609 #endif
3610 if (strncmp(display, "unix:", 5) == 0) {
3611 csock = unix_connect(display+5, errp);
3612 } else {
3613 csock = inet_connect(display, errp);
3615 if (csock < 0) {
3616 goto fail;
3618 vnc_connect(vs, csock, false, false);
3619 } else {
3620 /* listen for connects */
3621 char *dpy;
3622 dpy = g_malloc(256);
3623 if (strncmp(display, "unix:", 5) == 0) {
3624 pstrcpy(dpy, 256, "unix:");
3625 vs->lsock = unix_listen(display+5, dpy+5, 256-5, errp);
3626 } else {
3627 vs->lsock = inet_listen(display, dpy, 256,
3628 SOCK_STREAM, 5900, errp);
3629 if (vs->lsock < 0) {
3630 g_free(dpy);
3631 goto fail;
3633 #ifdef CONFIG_VNC_WS
3634 if (vs->websocket) {
3635 if (vs->ws_display) {
3636 vs->lwebsock = inet_listen(vs->ws_display, NULL, 256,
3637 SOCK_STREAM, 0, errp);
3638 } else {
3639 vs->lwebsock = inet_listen(vs->display, NULL, 256,
3640 SOCK_STREAM, 5700, errp);
3643 if (vs->lwebsock < 0) {
3644 if (vs->lsock) {
3645 close(vs->lsock);
3646 vs->lsock = -1;
3648 g_free(dpy);
3649 goto fail;
3652 #endif /* CONFIG_VNC_WS */
3654 g_free(to);
3655 g_free(display);
3656 g_free(vs->display);
3657 vs->display = dpy;
3658 qemu_set_fd_handler2(vs->lsock, NULL,
3659 vnc_listen_regular_read, NULL, vs);
3660 #ifdef CONFIG_VNC_WS
3661 if (vs->websocket) {
3662 qemu_set_fd_handler2(vs->lwebsock, NULL,
3663 vnc_listen_websocket_read, NULL, vs);
3665 #endif /* CONFIG_VNC_WS */
3667 return;
3669 fail:
3670 g_free(to);
3671 g_free(display);
3672 g_free(vs->display);
3673 vs->display = NULL;
3674 #ifdef CONFIG_VNC_WS
3675 g_free(vs->ws_display);
3676 vs->ws_display = NULL;
3677 #endif /* CONFIG_VNC_WS */
3680 void vnc_display_add_client(const char *id, int csock, bool skipauth)
3682 VncDisplay *vs = vnc_display_find(id);
3684 if (!vs) {
3685 return;
3687 vnc_connect(vs, csock, skipauth, false);
3690 QemuOpts *vnc_parse_func(const char *str)
3692 return qemu_opts_parse(qemu_find_opts("vnc"), str, 1);
3695 void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
3697 int i = 2;
3698 char *id;
3700 id = g_strdup("default");
3701 while (qemu_opts_find(olist, id)) {
3702 g_free(id);
3703 id = g_strdup_printf("vnc%d", i++);
3705 qemu_opts_set_id(opts, id);
3708 int vnc_init_func(QemuOpts *opts, void *opaque)
3710 Error *local_err = NULL;
3711 QemuOptsList *olist = qemu_find_opts("vnc");
3712 char *id = (char *)qemu_opts_id(opts);
3714 if (!id) {
3715 /* auto-assign id if not present */
3716 vnc_auto_assign_id(olist, opts);
3717 id = (char *)qemu_opts_id(opts);
3720 vnc_display_init(id);
3721 vnc_display_open(id, &local_err);
3722 if (local_err != NULL) {
3723 error_report("Failed to start VNC server on `%s': %s",
3724 qemu_opt_get(opts, "display"),
3725 error_get_pretty(local_err));
3726 error_free(local_err);
3727 exit(1);
3729 return 0;
3732 static void vnc_register_config(void)
3734 qemu_add_opts(&qemu_vnc_opts);
3736 machine_init(vnc_register_config);