]> git.proxmox.com Git - mirror_qemu.git/blame - ui/vnc.c
qemu-char: Fix missed data on unix socket
[mirror_qemu.git] / ui / vnc.c
CommitLineData
7d510b8c
FB
1/*
2 * QEMU VNC display driver
5fafdf24 3 *
7d510b8c
FB
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
19a490bf 6 * Copyright (C) 2009 Red Hat, Inc
5fafdf24 7 *
7d510b8c
FB
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
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.
25 */
26
19a490bf 27#include "vnc.h"
bd023f95 28#include "vnc-jobs.h"
40066175 29#include "trace.h"
1d0d59fe 30#include "hw/qdev.h"
9c17d615 31#include "sysemu/sysemu.h"
d49b6836 32#include "qemu/error-report.h"
1de7afc9
PB
33#include "qemu/sockets.h"
34#include "qemu/timer.h"
35#include "qemu/acl.h"
4db14629 36#include "qemu/config-file.h"
cc7a8ea7 37#include "qapi/qmp/qerror.h"
7b1b5d19 38#include "qapi/qmp/types.h"
2b54aa87 39#include "qmp-commands.h"
1de7afc9 40#include "qemu/osdep.h"
8d447d10 41#include "ui/input.h"
fb6ba0d5 42#include "qapi-event.h"
8e9b0d24 43#include "crypto/hash.h"
24236869 44
0f7b2864 45#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
2430ffe4 46#define VNC_REFRESH_INTERVAL_INC 50
0f7b2864 47#define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
999342a0
CC
48static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
49static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
24236869
FB
50
51#include "vnc_keysym.h"
800567a6 52#include "crypto/cipher.h"
70848515 53
d616ccc5
GH
54static QTAILQ_HEAD(, VncDisplay) vnc_displays =
55 QTAILQ_HEAD_INITIALIZER(vnc_displays);
a9ce8590 56
d467b679 57static int vnc_cursor_define(VncState *vs);
7bc9318b 58static void vnc_release_modifiers(VncState *vs);
d467b679 59
8cf36489
GH
60static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
61{
62#ifdef _VNC_DEBUG
63 static const char *mn[] = {
64 [0] = "undefined",
65 [VNC_SHARE_MODE_CONNECTING] = "connecting",
66 [VNC_SHARE_MODE_SHARED] = "shared",
67 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
68 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
69 };
70 fprintf(stderr, "%s/%d: %s -> %s\n", __func__,
71 vs->csock, mn[vs->share_mode], mn[mode]);
72#endif
73
e5f34cdd
GH
74 switch (vs->share_mode) {
75 case VNC_SHARE_MODE_CONNECTING:
76 vs->vd->num_connecting--;
77 break;
78 case VNC_SHARE_MODE_SHARED:
79 vs->vd->num_shared--;
80 break;
81 case VNC_SHARE_MODE_EXCLUSIVE:
8cf36489 82 vs->vd->num_exclusive--;
e5f34cdd
GH
83 break;
84 default:
85 break;
8cf36489 86 }
e5f34cdd 87
8cf36489 88 vs->share_mode = mode;
e5f34cdd
GH
89
90 switch (vs->share_mode) {
91 case VNC_SHARE_MODE_CONNECTING:
92 vs->vd->num_connecting++;
93 break;
94 case VNC_SHARE_MODE_SHARED:
95 vs->vd->num_shared++;
96 break;
97 case VNC_SHARE_MODE_EXCLUSIVE:
8cf36489 98 vs->vd->num_exclusive++;
e5f34cdd
GH
99 break;
100 default:
101 break;
8cf36489
GH
102 }
103}
104
1ff7df1a
AL
105static char *addr_to_string(const char *format,
106 struct sockaddr_storage *sa,
107 socklen_t salen) {
108 char *addr;
109 char host[NI_MAXHOST];
110 char serv[NI_MAXSERV];
111 int err;
457772e6 112 size_t addrlen;
1ff7df1a
AL
113
114 if ((err = getnameinfo((struct sockaddr *)sa, salen,
115 host, sizeof(host),
116 serv, sizeof(serv),
117 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
118 VNC_DEBUG("Cannot resolve address %d: %s\n",
119 err, gai_strerror(err));
120 return NULL;
121 }
122
457772e6 123 /* Enough for the existing format + the 2 vars we're
f425c278 124 * substituting in. */
457772e6 125 addrlen = strlen(format) + strlen(host) + strlen(serv);
7267c094 126 addr = g_malloc(addrlen + 1);
457772e6
AL
127 snprintf(addr, addrlen, format, host, serv);
128 addr[addrlen] = '\0';
1ff7df1a
AL
129
130 return addr;
131}
132
2f9606b3
AL
133
134char *vnc_socket_local_addr(const char *format, int fd) {
1ff7df1a
AL
135 struct sockaddr_storage sa;
136 socklen_t salen;
137
138 salen = sizeof(sa);
139 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
140 return NULL;
141
142 return addr_to_string(format, &sa, salen);
143}
144
2f9606b3 145char *vnc_socket_remote_addr(const char *format, int fd) {
1ff7df1a
AL
146 struct sockaddr_storage sa;
147 socklen_t salen;
148
149 salen = sizeof(sa);
150 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
151 return NULL;
152
153 return addr_to_string(format, &sa, salen);
154}
155
fb6ba0d5
WX
156static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
157 socklen_t salen)
d96fd29c 158{
fb6ba0d5 159 VncBasicInfo *info;
d96fd29c
LC
160 char host[NI_MAXHOST];
161 char serv[NI_MAXSERV];
162 int err;
163
164 if ((err = getnameinfo((struct sockaddr *)sa, salen,
165 host, sizeof(host),
166 serv, sizeof(serv),
167 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
168 VNC_DEBUG("Cannot resolve address %d: %s\n",
169 err, gai_strerror(err));
fb6ba0d5 170 return NULL;
d96fd29c
LC
171 }
172
fb6ba0d5
WX
173 info = g_malloc0(sizeof(VncBasicInfo));
174 info->host = g_strdup(host);
175 info->service = g_strdup(serv);
176 info->family = inet_netfamily(sa->ss_family);
177 return info;
d96fd29c
LC
178}
179
fb6ba0d5 180static VncBasicInfo *vnc_basic_info_get_from_server_addr(int fd)
d96fd29c
LC
181{
182 struct sockaddr_storage sa;
183 socklen_t salen;
184
185 salen = sizeof(sa);
186 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
fb6ba0d5 187 return NULL;
d96fd29c
LC
188 }
189
fb6ba0d5 190 return vnc_basic_info_get(&sa, salen);
d96fd29c
LC
191}
192
fb6ba0d5 193static VncBasicInfo *vnc_basic_info_get_from_remote_addr(int fd)
d96fd29c
LC
194{
195 struct sockaddr_storage sa;
196 socklen_t salen;
197
198 salen = sizeof(sa);
199 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
fb6ba0d5 200 return NULL;
d96fd29c
LC
201 }
202
fb6ba0d5 203 return vnc_basic_info_get(&sa, salen);
d96fd29c
LC
204}
205
1ff7df1a
AL
206static const char *vnc_auth_name(VncDisplay *vd) {
207 switch (vd->auth) {
208 case VNC_AUTH_INVALID:
209 return "invalid";
210 case VNC_AUTH_NONE:
211 return "none";
212 case VNC_AUTH_VNC:
213 return "vnc";
214 case VNC_AUTH_RA2:
215 return "ra2";
216 case VNC_AUTH_RA2NE:
217 return "ra2ne";
218 case VNC_AUTH_TIGHT:
219 return "tight";
220 case VNC_AUTH_ULTRA:
221 return "ultra";
222 case VNC_AUTH_TLS:
223 return "tls";
224 case VNC_AUTH_VENCRYPT:
225#ifdef CONFIG_VNC_TLS
226 switch (vd->subauth) {
227 case VNC_AUTH_VENCRYPT_PLAIN:
228 return "vencrypt+plain";
229 case VNC_AUTH_VENCRYPT_TLSNONE:
230 return "vencrypt+tls+none";
231 case VNC_AUTH_VENCRYPT_TLSVNC:
232 return "vencrypt+tls+vnc";
233 case VNC_AUTH_VENCRYPT_TLSPLAIN:
234 return "vencrypt+tls+plain";
235 case VNC_AUTH_VENCRYPT_X509NONE:
236 return "vencrypt+x509+none";
237 case VNC_AUTH_VENCRYPT_X509VNC:
238 return "vencrypt+x509+vnc";
239 case VNC_AUTH_VENCRYPT_X509PLAIN:
240 return "vencrypt+x509+plain";
28a76be8
AL
241 case VNC_AUTH_VENCRYPT_TLSSASL:
242 return "vencrypt+tls+sasl";
243 case VNC_AUTH_VENCRYPT_X509SASL:
244 return "vencrypt+x509+sasl";
1ff7df1a
AL
245 default:
246 return "vencrypt";
247 }
248#else
249 return "vencrypt";
250#endif
2f9606b3 251 case VNC_AUTH_SASL:
28a76be8 252 return "sasl";
1ff7df1a
AL
253 }
254 return "unknown";
255}
256
d616ccc5 257static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
a7789382 258{
fb6ba0d5 259 VncServerInfo *info;
d616ccc5 260 VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vd->lsock);
fb6ba0d5
WX
261 if (!bi) {
262 return NULL;
a7789382
LC
263 }
264
fb6ba0d5
WX
265 info = g_malloc(sizeof(*info));
266 info->base = bi;
267 info->has_auth = true;
d616ccc5 268 info->auth = g_strdup(vnc_auth_name(vd));
fb6ba0d5 269 return info;
a7789382
LC
270}
271
4a80dba3 272static void vnc_client_cache_auth(VncState *client)
1ff7df1a 273{
4a80dba3
LC
274 if (!client->info) {
275 return;
d96fd29c 276 }
1263b7d6
AL
277
278#ifdef CONFIG_VNC_TLS
279 if (client->tls.session &&
d96fd29c 280 client->tls.dname) {
fb6ba0d5
WX
281 client->info->has_x509_dname = true;
282 client->info->x509_dname = g_strdup(client->tls.dname);
d96fd29c 283 }
1263b7d6
AL
284#endif
285#ifdef CONFIG_VNC_SASL
286 if (client->sasl.conn &&
d96fd29c 287 client->sasl.username) {
fb6ba0d5
WX
288 client->info->has_sasl_username = true;
289 client->info->sasl_username = g_strdup(client->sasl.username);
d96fd29c 290 }
1263b7d6 291#endif
4a80dba3 292}
d96fd29c 293
4a80dba3
LC
294static void vnc_client_cache_addr(VncState *client)
295{
fb6ba0d5 296 VncBasicInfo *bi = vnc_basic_info_get_from_remote_addr(client->csock);
4a80dba3 297
fb6ba0d5
WX
298 if (bi) {
299 client->info = g_malloc0(sizeof(*client->info));
300 client->info->base = bi;
4a80dba3 301 }
1ff7df1a
AL
302}
303
fb6ba0d5 304static void vnc_qmp_event(VncState *vs, QAPIEvent event)
586153d9 305{
fb6ba0d5 306 VncServerInfo *si;
586153d9
LC
307
308 if (!vs->info) {
309 return;
310 }
fb6ba0d5 311 g_assert(vs->info->base);
586153d9 312
d616ccc5 313 si = vnc_server_info_get(vs->vd);
fb6ba0d5 314 if (!si) {
586153d9
LC
315 return;
316 }
317
fb6ba0d5
WX
318 switch (event) {
319 case QAPI_EVENT_VNC_CONNECTED:
320 qapi_event_send_vnc_connected(si, vs->info->base, &error_abort);
321 break;
322 case QAPI_EVENT_VNC_INITIALIZED:
323 qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
324 break;
325 case QAPI_EVENT_VNC_DISCONNECTED:
326 qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
327 break;
328 default:
329 break;
330 }
586153d9 331
fb6ba0d5 332 qapi_free_VncServerInfo(si);
586153d9
LC
333}
334
2b54aa87 335static VncClientInfo *qmp_query_vnc_client(const VncState *client)
a9ce8590 336{
2b54aa87
LC
337 struct sockaddr_storage sa;
338 socklen_t salen = sizeof(sa);
339 char host[NI_MAXHOST];
340 char serv[NI_MAXSERV];
341 VncClientInfo *info;
342
343 if (getpeername(client->csock, (struct sockaddr *)&sa, &salen) < 0) {
344 return NULL;
345 }
346
347 if (getnameinfo((struct sockaddr *)&sa, salen,
348 host, sizeof(host),
349 serv, sizeof(serv),
350 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
351 return NULL;
352 }
d96fd29c 353
2b54aa87 354 info = g_malloc0(sizeof(*info));
a589569f
WX
355 info->base = g_malloc0(sizeof(*info->base));
356 info->base->host = g_strdup(host);
357 info->base->service = g_strdup(serv);
358 info->base->family = inet_netfamily(sa.ss_family);
4478aa76 359 info->base->websocket = client->websocket;
d96fd29c
LC
360
361#ifdef CONFIG_VNC_TLS
2b54aa87
LC
362 if (client->tls.session && client->tls.dname) {
363 info->has_x509_dname = true;
364 info->x509_dname = g_strdup(client->tls.dname);
365 }
d96fd29c
LC
366#endif
367#ifdef CONFIG_VNC_SASL
2b54aa87
LC
368 if (client->sasl.conn && client->sasl.username) {
369 info->has_sasl_username = true;
370 info->sasl_username = g_strdup(client->sasl.username);
d96fd29c 371 }
2b54aa87 372#endif
1ff7df1a 373
2b54aa87 374 return info;
d96fd29c 375}
1ff7df1a 376
d616ccc5
GH
377static VncDisplay *vnc_display_find(const char *id)
378{
379 VncDisplay *vd;
380
381 if (id == NULL) {
382 return QTAILQ_FIRST(&vnc_displays);
383 }
384 QTAILQ_FOREACH(vd, &vnc_displays, next) {
385 if (strcmp(id, vd->id) == 0) {
386 return vd;
387 }
388 }
389 return NULL;
390}
391
2d29a436
GH
392static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
393{
394 VncClientInfoList *cinfo, *prev = NULL;
395 VncState *client;
396
397 QTAILQ_FOREACH(client, &vd->clients, next) {
398 cinfo = g_new0(VncClientInfoList, 1);
399 cinfo->value = qmp_query_vnc_client(client);
400 cinfo->next = prev;
401 prev = cinfo;
402 }
403 return prev;
404}
405
2b54aa87 406VncInfo *qmp_query_vnc(Error **errp)
d96fd29c 407{
2b54aa87 408 VncInfo *info = g_malloc0(sizeof(*info));
d616ccc5 409 VncDisplay *vd = vnc_display_find(NULL);
2b54aa87 410
bf7aa45e 411 if (vd == NULL || !vd->enabled) {
2b54aa87 412 info->enabled = false;
d96fd29c 413 } else {
2b54aa87
LC
414 struct sockaddr_storage sa;
415 socklen_t salen = sizeof(sa);
416 char host[NI_MAXHOST];
417 char serv[NI_MAXSERV];
1ff7df1a 418
2b54aa87
LC
419 info->enabled = true;
420
421 /* for compatibility with the original command */
422 info->has_clients = true;
2d29a436 423 info->clients = qmp_query_client_list(vd);
d96fd29c 424
d616ccc5 425 if (vd->lsock == -1) {
417b0b88
PB
426 return info;
427 }
428
d616ccc5 429 if (getsockname(vd->lsock, (struct sockaddr *)&sa,
2b54aa87 430 &salen) == -1) {
c6bd8c70 431 error_setg(errp, QERR_UNDEFINED_ERROR);
2b54aa87
LC
432 goto out_error;
433 }
d96fd29c 434
2b54aa87
LC
435 if (getnameinfo((struct sockaddr *)&sa, salen,
436 host, sizeof(host),
437 serv, sizeof(serv),
438 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
c6bd8c70 439 error_setg(errp, QERR_UNDEFINED_ERROR);
2b54aa87 440 goto out_error;
1ff7df1a 441 }
2b54aa87
LC
442
443 info->has_host = true;
444 info->host = g_strdup(host);
445
446 info->has_service = true;
447 info->service = g_strdup(serv);
448
449 info->has_family = true;
a589569f 450 info->family = inet_netfamily(sa.ss_family);
2b54aa87
LC
451
452 info->has_auth = true;
d616ccc5 453 info->auth = g_strdup(vnc_auth_name(vd));
a9ce8590 454 }
2b54aa87
LC
455
456 return info;
457
458out_error:
459 qapi_free_VncInfo(info);
460 return NULL;
a9ce8590
FB
461}
462
df887684 463static VncBasicInfoList *qmp_query_server_entry(int socket,
4478aa76 464 bool websocket,
df887684
GH
465 VncBasicInfoList *prev)
466{
467 VncBasicInfoList *list;
468 VncBasicInfo *info;
469 struct sockaddr_storage sa;
470 socklen_t salen = sizeof(sa);
471 char host[NI_MAXHOST];
472 char serv[NI_MAXSERV];
473
474 if (getsockname(socket, (struct sockaddr *)&sa, &salen) < 0 ||
475 getnameinfo((struct sockaddr *)&sa, salen,
476 host, sizeof(host), serv, sizeof(serv),
477 NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
478 return prev;
479 }
480
481 info = g_new0(VncBasicInfo, 1);
482 info->host = g_strdup(host);
483 info->service = g_strdup(serv);
484 info->family = inet_netfamily(sa.ss_family);
4478aa76 485 info->websocket = websocket;
df887684
GH
486
487 list = g_new0(VncBasicInfoList, 1);
488 list->value = info;
489 list->next = prev;
490 return list;
491}
492
493static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
494{
495 switch (vd->auth) {
496 case VNC_AUTH_VNC:
497 info->auth = VNC_PRIMARY_AUTH_VNC;
498 break;
499 case VNC_AUTH_RA2:
500 info->auth = VNC_PRIMARY_AUTH_RA2;
501 break;
502 case VNC_AUTH_RA2NE:
503 info->auth = VNC_PRIMARY_AUTH_RA2NE;
504 break;
505 case VNC_AUTH_TIGHT:
506 info->auth = VNC_PRIMARY_AUTH_TIGHT;
507 break;
508 case VNC_AUTH_ULTRA:
509 info->auth = VNC_PRIMARY_AUTH_ULTRA;
510 break;
511 case VNC_AUTH_TLS:
512 info->auth = VNC_PRIMARY_AUTH_TLS;
513 break;
514 case VNC_AUTH_VENCRYPT:
515 info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
516#ifdef CONFIG_VNC_TLS
517 info->has_vencrypt = true;
518 switch (vd->subauth) {
519 case VNC_AUTH_VENCRYPT_PLAIN:
520 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
521 break;
522 case VNC_AUTH_VENCRYPT_TLSNONE:
523 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
524 break;
525 case VNC_AUTH_VENCRYPT_TLSVNC:
526 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
527 break;
528 case VNC_AUTH_VENCRYPT_TLSPLAIN:
529 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
530 break;
531 case VNC_AUTH_VENCRYPT_X509NONE:
532 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
533 break;
534 case VNC_AUTH_VENCRYPT_X509VNC:
535 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
536 break;
537 case VNC_AUTH_VENCRYPT_X509PLAIN:
538 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
539 break;
540 case VNC_AUTH_VENCRYPT_TLSSASL:
541 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
542 break;
543 case VNC_AUTH_VENCRYPT_X509SASL:
544 info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
545 break;
546 default:
547 info->has_vencrypt = false;
548 break;
549 }
550#endif
551 break;
552 case VNC_AUTH_SASL:
553 info->auth = VNC_PRIMARY_AUTH_SASL;
554 break;
555 case VNC_AUTH_NONE:
556 default:
557 info->auth = VNC_PRIMARY_AUTH_NONE;
558 break;
559 }
560}
561
562VncInfo2List *qmp_query_vnc_servers(Error **errp)
563{
564 VncInfo2List *item, *prev = NULL;
565 VncInfo2 *info;
566 VncDisplay *vd;
567 DeviceState *dev;
568
569 QTAILQ_FOREACH(vd, &vnc_displays, next) {
570 info = g_new0(VncInfo2, 1);
571 info->id = g_strdup(vd->id);
572 info->clients = qmp_query_client_list(vd);
573 qmp_query_auth(vd, info);
574 if (vd->dcl.con) {
575 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
576 "device", NULL));
577 info->has_display = true;
578 info->display = g_strdup(dev->id);
579 }
580 if (vd->lsock != -1) {
4478aa76 581 info->server = qmp_query_server_entry(vd->lsock, false,
df887684
GH
582 info->server);
583 }
df887684 584 if (vd->lwebsock != -1) {
4478aa76
GH
585 info->server = qmp_query_server_entry(vd->lwebsock, true,
586 info->server);
df887684 587 }
df887684
GH
588
589 item = g_new0(VncInfo2List, 1);
590 item->value = info;
591 item->next = prev;
592 prev = item;
593 }
594 return prev;
595}
596
24236869
FB
597/* TODO
598 1) Get the queue working for IO.
599 2) there is some weirdness when using the -S option (the screen is grey
600 and not totally invalidated
601 3) resolutions > 1024
602*/
603
38ee14f4 604static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
198a0039 605static void vnc_disconnect_start(VncState *vs);
24236869 606
753b4053 607static void vnc_colordepth(VncState *vs);
1fc62412
SS
608static void framebuffer_update_request(VncState *vs, int incremental,
609 int x_position, int y_position,
610 int w, int h);
0f7b2864 611static void vnc_refresh(DisplayChangeListener *dcl);
1fc62412 612static int vnc_refresh_server_surface(VncDisplay *vd);
7eac3a87 613
bea60dd7
PL
614static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
615 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
616 int width, int height,
617 int x, int y, int w, int h) {
91937225
PL
618 /* this is needed this to ensure we updated all affected
619 * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
b4c85ddc
PL
620 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
621 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
0486e8a7 622
9f64916d
GH
623 x = MIN(x, width);
624 y = MIN(y, height);
625 w = MIN(x + w, width) - x;
91937225 626 h = MIN(y + h, height);
788abf8e 627
b4c85ddc 628 for (; y < h; y++) {
bea60dd7 629 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
91937225 630 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
b4c85ddc 631 }
24236869
FB
632}
633
bea60dd7
PL
634static void vnc_dpy_update(DisplayChangeListener *dcl,
635 int x, int y, int w, int h)
636{
637 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
638 struct VncSurface *s = &vd->guest;
639 int width = pixman_image_get_width(vd->server);
640 int height = pixman_image_get_height(vd->server);
641
642 vnc_set_area_dirty(s->dirty, width, height, x, y, w, h);
643}
644
70a4568f
CC
645void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
646 int32_t encoding)
24236869
FB
647{
648 vnc_write_u16(vs, x);
649 vnc_write_u16(vs, y);
650 vnc_write_u16(vs, w);
651 vnc_write_u16(vs, h);
652
653 vnc_write_s32(vs, encoding);
654}
655
2f9606b3 656void buffer_reserve(Buffer *buffer, size_t len)
89064286
AL
657{
658 if ((buffer->capacity - buffer->offset) < len) {
28a76be8 659 buffer->capacity += (len + 1024);
7267c094 660 buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
89064286
AL
661 }
662}
663
71a8cdec 664static int buffer_empty(Buffer *buffer)
89064286
AL
665{
666 return buffer->offset == 0;
667}
668
7536ee4b 669uint8_t *buffer_end(Buffer *buffer)
89064286
AL
670{
671 return buffer->buffer + buffer->offset;
672}
673
2f9606b3 674void buffer_reset(Buffer *buffer)
89064286 675{
28a76be8 676 buffer->offset = 0;
89064286
AL
677}
678
5d418e3b
CC
679void buffer_free(Buffer *buffer)
680{
7267c094 681 g_free(buffer->buffer);
5d418e3b
CC
682 buffer->offset = 0;
683 buffer->capacity = 0;
684 buffer->buffer = NULL;
685}
686
2f9606b3 687void buffer_append(Buffer *buffer, const void *data, size_t len)
89064286
AL
688{
689 memcpy(buffer->buffer + buffer->offset, data, len);
690 buffer->offset += len;
691}
692
32ed2680
TH
693void buffer_advance(Buffer *buf, size_t len)
694{
695 memmove(buf->buffer, buf->buffer + len,
696 (buf->offset - len));
697 buf->offset -= len;
698}
699
621aaeb9
GH
700static void vnc_desktop_resize(VncState *vs)
701{
621aaeb9
GH
702 if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
703 return;
704 }
bea60dd7
PL
705 if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
706 vs->client_height == pixman_image_get_height(vs->vd->server)) {
1d4b638a
GH
707 return;
708 }
bea60dd7
PL
709 vs->client_width = pixman_image_get_width(vs->vd->server);
710 vs->client_height = pixman_image_get_height(vs->vd->server);
bd023f95 711 vnc_lock_output(vs);
621aaeb9
GH
712 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
713 vnc_write_u8(vs, 0);
714 vnc_write_u16(vs, 1); /* number of rects */
5862d195 715 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
621aaeb9 716 VNC_ENCODING_DESKTOPRESIZE);
bd023f95 717 vnc_unlock_output(vs);
621aaeb9
GH
718 vnc_flush(vs);
719}
720
bd023f95
CC
721static void vnc_abort_display_jobs(VncDisplay *vd)
722{
723 VncState *vs;
724
725 QTAILQ_FOREACH(vs, &vd->clients, next) {
726 vnc_lock_output(vs);
727 vs->abort = true;
728 vnc_unlock_output(vs);
729 }
730 QTAILQ_FOREACH(vs, &vd->clients, next) {
731 vnc_jobs_join(vs);
732 }
733 QTAILQ_FOREACH(vs, &vd->clients, next) {
734 vnc_lock_output(vs);
735 vs->abort = false;
736 vnc_unlock_output(vs);
737 }
738}
bd023f95 739
9f64916d
GH
740int vnc_server_fb_stride(VncDisplay *vd)
741{
742 return pixman_image_get_stride(vd->server);
743}
744
745void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
746{
747 uint8_t *ptr;
748
749 ptr = (uint8_t *)pixman_image_get_data(vd->server);
750 ptr += y * vnc_server_fb_stride(vd);
751 ptr += x * VNC_SERVER_FB_BYTES;
752 return ptr;
753}
754
c12aeb86 755static void vnc_dpy_switch(DisplayChangeListener *dcl,
c12aeb86 756 DisplaySurface *surface)
24236869 757{
21ef45d7 758 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
41b4bef6 759 VncState *vs;
bea60dd7 760 int width, height;
1fc62412 761
bd023f95
CC
762 vnc_abort_display_jobs(vd);
763
1fc62412 764 /* server surface */
9f64916d 765 qemu_pixman_image_unref(vd->server);
d39fa6d8 766 vd->ds = surface;
bea60dd7
PL
767 width = MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
768 VNC_DIRTY_PIXELS_PER_BIT));
769 height = MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
9f64916d 770 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
bea60dd7 771 width, height, NULL, 0);
24236869 772
6baebed7 773 /* guest surface */
9f64916d 774#if 0 /* FIXME */
1fc62412 775 if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
a528b80c 776 console_color_init(ds);
9f64916d
GH
777#endif
778 qemu_pixman_image_unref(vd->guest.fb);
d39fa6d8
GH
779 vd->guest.fb = pixman_image_ref(surface->image);
780 vd->guest.format = surface->format;
bea60dd7
PL
781 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
782 vnc_set_area_dirty(vd->guest.dirty, width, height, 0, 0,
783 width, height);
24236869 784
41b4bef6 785 QTAILQ_FOREACH(vs, &vd->clients, next) {
1fc62412 786 vnc_colordepth(vs);
1d4b638a 787 vnc_desktop_resize(vs);
d467b679
GH
788 if (vs->vd->cursor) {
789 vnc_cursor_define(vs);
790 }
bea60dd7
PL
791 memset(vs->dirty, 0x00, sizeof(vs->dirty));
792 vnc_set_area_dirty(vs->dirty, width, height, 0, 0,
793 width, height);
753b4053
AL
794 }
795}
796
3512779a 797/* fastest code */
9f64916d 798static void vnc_write_pixels_copy(VncState *vs,
d467b679 799 void *pixels, int size)
3512779a
FB
800{
801 vnc_write(vs, pixels, size);
802}
803
804/* slowest but generic code. */
70a4568f 805void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
3512779a 806{
7eac3a87 807 uint8_t r, g, b;
1fc62412 808
9f64916d
GH
809#if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
810 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
811 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
812 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
813#else
814# error need some bits here if you change VNC_SERVER_FB_FORMAT
815#endif
816 v = (r << vs->client_pf.rshift) |
817 (g << vs->client_pf.gshift) |
818 (b << vs->client_pf.bshift);
819 switch (vs->client_pf.bytes_per_pixel) {
3512779a
FB
820 case 1:
821 buf[0] = v;
822 break;
823 case 2:
9f64916d 824 if (vs->client_be) {
3512779a
FB
825 buf[0] = v >> 8;
826 buf[1] = v;
827 } else {
828 buf[1] = v >> 8;
829 buf[0] = v;
830 }
831 break;
832 default:
833 case 4:
9f64916d 834 if (vs->client_be) {
3512779a
FB
835 buf[0] = v >> 24;
836 buf[1] = v >> 16;
837 buf[2] = v >> 8;
838 buf[3] = v;
839 } else {
840 buf[3] = v >> 24;
841 buf[2] = v >> 16;
842 buf[1] = v >> 8;
843 buf[0] = v;
844 }
845 break;
846 }
847}
848
9f64916d 849static void vnc_write_pixels_generic(VncState *vs,
d467b679 850 void *pixels1, int size)
3512779a 851{
3512779a 852 uint8_t buf[4];
3512779a 853
9f64916d 854 if (VNC_SERVER_FB_BYTES == 4) {
7eac3a87
AL
855 uint32_t *pixels = pixels1;
856 int n, i;
857 n = size >> 2;
9f64916d 858 for (i = 0; i < n; i++) {
7eac3a87 859 vnc_convert_pixel(vs, buf, pixels[i]);
9f64916d 860 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
7eac3a87 861 }
3512779a
FB
862 }
863}
864
a885211e 865int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
24236869
FB
866{
867 int i;
60fe76f3 868 uint8_t *row;
1fc62412 869 VncDisplay *vd = vs->vd;
24236869 870
9f64916d 871 row = vnc_server_fb_ptr(vd, x, y);
24236869 872 for (i = 0; i < h; i++) {
9f64916d
GH
873 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
874 row += vnc_server_fb_stride(vd);
24236869 875 }
a885211e 876 return 1;
24236869
FB
877}
878
bd023f95 879int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
24236869 880{
a885211e
CC
881 int n = 0;
882
fb437313 883 switch(vs->vnc_encoding) {
28a76be8 884 case VNC_ENCODING_ZLIB:
a885211e 885 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
28a76be8
AL
886 break;
887 case VNC_ENCODING_HEXTILE:
888 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
a885211e 889 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
28a76be8 890 break;
380282b0
CC
891 case VNC_ENCODING_TIGHT:
892 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
893 break;
efe556ad
CC
894 case VNC_ENCODING_TIGHT_PNG:
895 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
896 break;
148954fa
CC
897 case VNC_ENCODING_ZRLE:
898 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
899 break;
900 case VNC_ENCODING_ZYWRLE:
901 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
902 break;
28a76be8
AL
903 default:
904 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
a885211e 905 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
28a76be8 906 break;
fb437313 907 }
a885211e 908 return n;
24236869
FB
909}
910
753b4053 911static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
24236869 912{
3e28c9ad 913 /* send bitblit op to the vnc client */
bd023f95 914 vnc_lock_output(vs);
46a183da 915 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
24236869
FB
916 vnc_write_u8(vs, 0);
917 vnc_write_u16(vs, 1); /* number of rects */
29fa4ed9 918 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
24236869
FB
919 vnc_write_u16(vs, src_x);
920 vnc_write_u16(vs, src_y);
bd023f95 921 vnc_unlock_output(vs);
24236869
FB
922 vnc_flush(vs);
923}
924
7c20b4a3 925static void vnc_dpy_copy(DisplayChangeListener *dcl,
7c20b4a3
GH
926 int src_x, int src_y,
927 int dst_x, int dst_y, int w, int h)
753b4053 928{
21ef45d7 929 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
198a0039 930 VncState *vs, *vn;
1fc62412
SS
931 uint8_t *src_row;
932 uint8_t *dst_row;
9f64916d 933 int i, x, y, pitch, inc, w_lim, s;
1fc62412 934 int cmp_bytes;
198a0039 935
1fc62412 936 vnc_refresh_server_surface(vd);
41b4bef6 937 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
198a0039
GH
938 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
939 vs->force_update = 1;
38ee14f4 940 vnc_update_client(vs, 1, true);
198a0039
GH
941 /* vs might be free()ed here */
942 }
943 }
944
1fc62412 945 /* do bitblit op on the local surface too */
9f64916d
GH
946 pitch = vnc_server_fb_stride(vd);
947 src_row = vnc_server_fb_ptr(vd, src_x, src_y);
948 dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
1fc62412
SS
949 y = dst_y;
950 inc = 1;
951 if (dst_y > src_y) {
952 /* copy backwards */
953 src_row += pitch * (h-1);
954 dst_row += pitch * (h-1);
955 pitch = -pitch;
956 y = dst_y + h - 1;
957 inc = -1;
958 }
b4c85ddc
PL
959 w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
960 if (w_lim < 0) {
1fc62412 961 w_lim = w;
b4c85ddc
PL
962 } else {
963 w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
964 }
1fc62412
SS
965 for (i = 0; i < h; i++) {
966 for (x = 0; x <= w_lim;
967 x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
968 if (x == w_lim) {
969 if ((s = w - w_lim) == 0)
970 break;
971 } else if (!x) {
b4c85ddc
PL
972 s = (VNC_DIRTY_PIXELS_PER_BIT -
973 (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
1fc62412
SS
974 s = MIN(s, w_lim);
975 } else {
b4c85ddc 976 s = VNC_DIRTY_PIXELS_PER_BIT;
1fc62412 977 }
9f64916d 978 cmp_bytes = s * VNC_SERVER_FB_BYTES;
1fc62412
SS
979 if (memcmp(src_row, dst_row, cmp_bytes) == 0)
980 continue;
981 memmove(dst_row, src_row, cmp_bytes);
41b4bef6
AS
982 QTAILQ_FOREACH(vs, &vd->clients, next) {
983 if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
b4c85ddc
PL
984 set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
985 vs->dirty[y]);
41b4bef6 986 }
1fc62412
SS
987 }
988 }
9f64916d
GH
989 src_row += pitch - w * VNC_SERVER_FB_BYTES;
990 dst_row += pitch - w * VNC_SERVER_FB_BYTES;
1fc62412
SS
991 y += inc;
992 }
993
41b4bef6
AS
994 QTAILQ_FOREACH(vs, &vd->clients, next) {
995 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
753b4053 996 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
41b4bef6 997 }
753b4053
AL
998 }
999}
1000
7c20b4a3 1001static void vnc_mouse_set(DisplayChangeListener *dcl,
7c20b4a3 1002 int x, int y, int visible)
d467b679
GH
1003{
1004 /* can we ask the client(s) to move the pointer ??? */
1005}
1006
1007static int vnc_cursor_define(VncState *vs)
1008{
1009 QEMUCursor *c = vs->vd->cursor;
d467b679
GH
1010 int isize;
1011
1012 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
d01f9595 1013 vnc_lock_output(vs);
d467b679
GH
1014 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1015 vnc_write_u8(vs, 0); /* padding */
1016 vnc_write_u16(vs, 1); /* # of rects */
1017 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1018 VNC_ENCODING_RICH_CURSOR);
9f64916d
GH
1019 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
1020 vnc_write_pixels_generic(vs, c->data, isize);
d467b679 1021 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
d01f9595 1022 vnc_unlock_output(vs);
d467b679
GH
1023 return 0;
1024 }
1025 return -1;
1026}
1027
7c20b4a3 1028static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
7c20b4a3 1029 QEMUCursor *c)
d467b679 1030{
d616ccc5 1031 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
d467b679
GH
1032 VncState *vs;
1033
1034 cursor_put(vd->cursor);
7267c094 1035 g_free(vd->cursor_mask);
d467b679
GH
1036
1037 vd->cursor = c;
1038 cursor_get(vd->cursor);
1039 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
7267c094 1040 vd->cursor_mask = g_malloc0(vd->cursor_msize);
d467b679
GH
1041 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1042
1043 QTAILQ_FOREACH(vs, &vd->clients, next) {
1044 vnc_cursor_define(vs);
1045 }
1046}
1047
4769a881 1048static int find_and_clear_dirty_height(VncState *vs,
6c71a539 1049 int y, int last_x, int x, int height)
24236869
FB
1050{
1051 int h;
1052
6c71a539 1053 for (h = 1; h < (height - y); h++) {
bc2429b9 1054 if (!test_bit(last_x, vs->dirty[y + h])) {
28a76be8 1055 break;
bc2429b9 1056 }
863d7c91 1057 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
24236869
FB
1058 }
1059
1060 return h;
1061}
1062
38ee14f4 1063static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
24236869 1064{
63658280 1065 vs->has_dirty += has_dirty;
24236869 1066 if (vs->need_update && vs->csock != -1) {
1fc62412 1067 VncDisplay *vd = vs->vd;
bd023f95 1068 VncJob *job;
28a76be8 1069 int y;
2f487a3d 1070 int height, width;
bd023f95
CC
1071 int n = 0;
1072
703bc68f 1073 if (vs->output.offset && !vs->audio_cap && !vs->force_update)
c522d0e2 1074 /* kernel send buffers are full -> drop frames to throttle */
2430ffe4 1075 return 0;
a0ecfb73 1076
63658280 1077 if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
2430ffe4 1078 return 0;
28a76be8 1079
6baebed7
AL
1080 /*
1081 * Send screen updates to the vnc client using the server
1082 * surface and server dirty map. guest surface updates
1083 * happening in parallel don't disturb us, the next pass will
1084 * send them to the client.
1085 */
bd023f95 1086 job = vnc_job_new(vs);
28a76be8 1087
bea60dd7
PL
1088 height = pixman_image_get_height(vd->server);
1089 width = pixman_image_get_width(vd->server);
847ce6a1 1090
12b316d4
PL
1091 y = 0;
1092 for (;;) {
1093 int x, h;
1094 unsigned long x2;
1095 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1096 height * VNC_DIRTY_BPL(vs),
1097 y * VNC_DIRTY_BPL(vs));
1098 if (offset == height * VNC_DIRTY_BPL(vs)) {
1099 /* no more dirty bits */
1100 break;
28a76be8 1101 }
12b316d4
PL
1102 y = offset / VNC_DIRTY_BPL(vs);
1103 x = offset % VNC_DIRTY_BPL(vs);
1104 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1105 VNC_DIRTY_BPL(vs), x);
1106 bitmap_clear(vs->dirty[y], x, x2 - x);
1107 h = find_and_clear_dirty_height(vs, y, x, x2, height);
2f487a3d
PL
1108 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1109 if (x2 > x) {
1110 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1111 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1112 }
0e7d6f60
PL
1113 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1114 y += h;
1115 if (y == height) {
1116 break;
1117 }
1118 }
28a76be8 1119 }
bd023f95
CC
1120
1121 vnc_job_push(job);
eb214ff8
GH
1122 if (sync) {
1123 vnc_jobs_join(vs);
1124 }
c522d0e2 1125 vs->force_update = 0;
63658280 1126 vs->has_dirty = 0;
bd023f95 1127 return n;
24236869 1128 }
24236869 1129
38ee14f4 1130 if (vs->csock == -1) {
198a0039 1131 vnc_disconnect_finish(vs);
38ee14f4
GH
1132 } else if (sync) {
1133 vnc_jobs_join(vs);
1134 }
2430ffe4
SS
1135
1136 return 0;
24236869
FB
1137}
1138
429a8ed3 1139/* audio */
1140static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1141{
1142 VncState *vs = opaque;
1143
1144 switch (cmd) {
1145 case AUD_CNOTIFY_DISABLE:
bd023f95 1146 vnc_lock_output(vs);
46a183da
DB
1147 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1148 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1149 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
bd023f95 1150 vnc_unlock_output(vs);
429a8ed3 1151 vnc_flush(vs);
1152 break;
1153
1154 case AUD_CNOTIFY_ENABLE:
bd023f95 1155 vnc_lock_output(vs);
46a183da
DB
1156 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1157 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1158 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
bd023f95 1159 vnc_unlock_output(vs);
429a8ed3 1160 vnc_flush(vs);
1161 break;
1162 }
1163}
1164
1165static void audio_capture_destroy(void *opaque)
1166{
1167}
1168
1169static void audio_capture(void *opaque, void *buf, int size)
1170{
1171 VncState *vs = opaque;
1172
bd023f95 1173 vnc_lock_output(vs);
46a183da
DB
1174 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1175 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1176 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
429a8ed3 1177 vnc_write_u32(vs, size);
1178 vnc_write(vs, buf, size);
bd023f95 1179 vnc_unlock_output(vs);
429a8ed3 1180 vnc_flush(vs);
1181}
1182
1183static void audio_add(VncState *vs)
1184{
1185 struct audio_capture_ops ops;
1186
1187 if (vs->audio_cap) {
027a79c3 1188 error_report("audio already running");
429a8ed3 1189 return;
1190 }
1191
1192 ops.notify = audio_capture_notify;
1193 ops.destroy = audio_capture_destroy;
1194 ops.capture = audio_capture;
1195
1a7dafce 1196 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
429a8ed3 1197 if (!vs->audio_cap) {
027a79c3 1198 error_report("Failed to add audio capture");
429a8ed3 1199 }
1200}
1201
1202static void audio_del(VncState *vs)
1203{
1204 if (vs->audio_cap) {
1205 AUD_del_capture(vs->audio_cap, vs);
1206 vs->audio_cap = NULL;
1207 }
1208}
1209
198a0039
GH
1210static void vnc_disconnect_start(VncState *vs)
1211{
1212 if (vs->csock == -1)
1213 return;
8cf36489 1214 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
82e1cc4b 1215 qemu_set_fd_handler(vs->csock, NULL, NULL, NULL);
198a0039
GH
1216 closesocket(vs->csock);
1217 vs->csock = -1;
1218}
1219
7536ee4b 1220void vnc_disconnect_finish(VncState *vs)
198a0039 1221{
7d964c9d
CC
1222 int i;
1223
bd023f95
CC
1224 vnc_jobs_join(vs); /* Wait encoding jobs */
1225
1226 vnc_lock_output(vs);
fb6ba0d5 1227 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
0d72f3d3 1228
5d418e3b
CC
1229 buffer_free(&vs->input);
1230 buffer_free(&vs->output);
7536ee4b
TH
1231 buffer_free(&vs->ws_input);
1232 buffer_free(&vs->ws_output);
4a80dba3 1233
fb6ba0d5 1234 qapi_free_VncClientInfo(vs->info);
4a80dba3 1235
161c4f20 1236 vnc_zlib_clear(vs);
380282b0 1237 vnc_tight_clear(vs);
148954fa 1238 vnc_zrle_clear(vs);
161c4f20 1239
198a0039
GH
1240#ifdef CONFIG_VNC_TLS
1241 vnc_tls_client_cleanup(vs);
1242#endif /* CONFIG_VNC_TLS */
1243#ifdef CONFIG_VNC_SASL
1244 vnc_sasl_client_cleanup(vs);
1245#endif /* CONFIG_VNC_SASL */
1246 audio_del(vs);
7bc9318b 1247 vnc_release_modifiers(vs);
198a0039 1248
6fd8e79a
TH
1249 if (vs->initialized) {
1250 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1251 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1252 }
41b4bef6 1253
3a0558b5
GH
1254 if (vs->vd->lock_key_sync)
1255 qemu_remove_led_event_handler(vs->led);
bd023f95
CC
1256 vnc_unlock_output(vs);
1257
bd023f95 1258 qemu_mutex_destroy(&vs->output_mutex);
6fd8e79a
TH
1259 if (vs->bh != NULL) {
1260 qemu_bh_delete(vs->bh);
1261 }
175b2a6e 1262 buffer_free(&vs->jobs_buffer);
175b2a6e 1263
7d964c9d 1264 for (i = 0; i < VNC_STAT_ROWS; ++i) {
7267c094 1265 g_free(vs->lossy_rect[i]);
7d964c9d 1266 }
7267c094
AL
1267 g_free(vs->lossy_rect);
1268 g_free(vs);
198a0039 1269}
2f9606b3
AL
1270
1271int vnc_client_io_error(VncState *vs, int ret, int last_errno)
24236869
FB
1272{
1273 if (ret == 0 || ret == -1) {
ea01e5fd
AZ
1274 if (ret == -1) {
1275 switch (last_errno) {
1276 case EINTR:
1277 case EAGAIN:
1278#ifdef _WIN32
1279 case WSAEWOULDBLOCK:
1280#endif
1281 return 0;
1282 default:
1283 break;
1284 }
1285 }
24236869 1286
198a0039
GH
1287 VNC_DEBUG("Closing down client sock: ret %d, errno %d\n",
1288 ret, ret < 0 ? last_errno : 0);
1289 vnc_disconnect_start(vs);
6baebed7 1290
28a76be8 1291 return 0;
24236869
FB
1292 }
1293 return ret;
1294}
1295
5fb6c7a8
AL
1296
1297void vnc_client_error(VncState *vs)
24236869 1298{
198a0039
GH
1299 VNC_DEBUG("Closing down client sock: protocol error\n");
1300 vnc_disconnect_start(vs);
24236869
FB
1301}
1302
0057a0d5
TH
1303#ifdef CONFIG_VNC_TLS
1304static long vnc_client_write_tls(gnutls_session_t *session,
1305 const uint8_t *data,
1306 size_t datalen)
1307{
1308 long ret = gnutls_write(*session, data, datalen);
1309 if (ret < 0) {
1310 if (ret == GNUTLS_E_AGAIN) {
1311 errno = EAGAIN;
1312 } else {
1313 errno = EIO;
1314 }
1315 ret = -1;
1316 }
1317 return ret;
1318}
1319#endif /* CONFIG_VNC_TLS */
2f9606b3
AL
1320
1321/*
1322 * Called to write a chunk of data to the client socket. The data may
1323 * be the raw data, or may have already been encoded by SASL.
1324 * The data will be written either straight onto the socket, or
1325 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1326 *
1327 * NB, it is theoretically possible to have 2 layers of encryption,
1328 * both SASL, and this TLS layer. It is highly unlikely in practice
1329 * though, since SASL encryption will typically be a no-op if TLS
1330 * is active
1331 *
1332 * Returns the number of bytes written, which may be less than
1333 * the requested 'datalen' if the socket would block. Returns
1334 * -1 on error, and disconnects the client socket.
1335 */
1336long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
24236869 1337{
ceb5caaf 1338 long ret;
eb38c52c 1339#ifdef CONFIG_VNC_TLS
5fb6c7a8 1340 if (vs->tls.session) {
0057a0d5
TH
1341 ret = vnc_client_write_tls(&vs->tls.session, data, datalen);
1342 } else {
0057a0d5 1343#endif /* CONFIG_VNC_TLS */
7b45a00d 1344 ret = send(vs->csock, (const void *)data, datalen, 0);
0057a0d5
TH
1345#ifdef CONFIG_VNC_TLS
1346 }
8d5d2d4c 1347#endif /* CONFIG_VNC_TLS */
23decc87 1348 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
2f9606b3
AL
1349 return vnc_client_io_error(vs, ret, socket_error());
1350}
1351
1352
1353/*
1354 * Called to write buffered data to the client socket, when not
1355 * using any SASL SSF encryption layers. Will write as much data
1356 * as possible without blocking. If all buffered data is written,
1357 * will switch the FD poll() handler back to read monitoring.
1358 *
1359 * Returns the number of bytes written, which may be less than
1360 * the buffered output data if the socket would block. Returns
1361 * -1 on error, and disconnects the client socket.
1362 */
1363static long vnc_client_write_plain(VncState *vs)
1364{
1365 long ret;
1366
1367#ifdef CONFIG_VNC_SASL
23decc87 1368 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
2f9606b3
AL
1369 vs->output.buffer, vs->output.capacity, vs->output.offset,
1370 vs->sasl.waitWriteSSF);
1371
1372 if (vs->sasl.conn &&
1373 vs->sasl.runSSF &&
1374 vs->sasl.waitWriteSSF) {
1375 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1376 if (ret)
1377 vs->sasl.waitWriteSSF -= ret;
1378 } else
1379#endif /* CONFIG_VNC_SASL */
1380 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
24236869 1381 if (!ret)
2f9606b3 1382 return 0;
24236869 1383
32ed2680 1384 buffer_advance(&vs->output, ret);
24236869
FB
1385
1386 if (vs->output.offset == 0) {
82e1cc4b 1387 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
24236869 1388 }
2f9606b3
AL
1389
1390 return ret;
1391}
1392
1393
1394/*
1395 * First function called whenever there is data to be written to
1396 * the client socket. Will delegate actual work according to whether
1397 * SASL SSF layers are enabled (thus requiring encryption calls)
1398 */
bd023f95 1399static void vnc_client_write_locked(void *opaque)
2f9606b3 1400{
2f9606b3
AL
1401 VncState *vs = opaque;
1402
1403#ifdef CONFIG_VNC_SASL
1404 if (vs->sasl.conn &&
1405 vs->sasl.runSSF &&
9678d950
BS
1406 !vs->sasl.waitWriteSSF) {
1407 vnc_client_write_sasl(vs);
1408 } else
2f9606b3 1409#endif /* CONFIG_VNC_SASL */
7536ee4b 1410 {
7536ee4b
TH
1411 if (vs->encode_ws) {
1412 vnc_client_write_ws(vs);
8e9b0d24 1413 } else {
7536ee4b
TH
1414 vnc_client_write_plain(vs);
1415 }
1416 }
24236869
FB
1417}
1418
bd023f95
CC
1419void vnc_client_write(void *opaque)
1420{
1421 VncState *vs = opaque;
1422
1423 vnc_lock_output(vs);
8e9b0d24 1424 if (vs->output.offset || vs->ws_output.offset) {
bd023f95 1425 vnc_client_write_locked(opaque);
ac71103d 1426 } else if (vs->csock != -1) {
82e1cc4b 1427 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
bd023f95
CC
1428 }
1429 vnc_unlock_output(vs);
1430}
1431
5fb6c7a8 1432void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
24236869
FB
1433{
1434 vs->read_handler = func;
1435 vs->read_handler_expect = expecting;
1436}
1437
0057a0d5
TH
1438#ifdef CONFIG_VNC_TLS
1439static long vnc_client_read_tls(gnutls_session_t *session, uint8_t *data,
1440 size_t datalen)
1441{
1442 long ret = gnutls_read(*session, data, datalen);
1443 if (ret < 0) {
1444 if (ret == GNUTLS_E_AGAIN) {
1445 errno = EAGAIN;
1446 } else {
1447 errno = EIO;
1448 }
1449 ret = -1;
1450 }
1451 return ret;
1452}
1453#endif /* CONFIG_VNC_TLS */
2f9606b3
AL
1454
1455/*
1456 * Called to read a chunk of data from the client socket. The data may
1457 * be the raw data, or may need to be further decoded by SASL.
1458 * The data will be read either straight from to the socket, or
1459 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1460 *
1461 * NB, it is theoretically possible to have 2 layers of encryption,
1462 * both SASL, and this TLS layer. It is highly unlikely in practice
1463 * though, since SASL encryption will typically be a no-op if TLS
1464 * is active
1465 *
1466 * Returns the number of bytes read, which may be less than
1467 * the requested 'datalen' if the socket would block. Returns
1468 * -1 on error, and disconnects the client socket.
1469 */
1470long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
24236869 1471{
ceb5caaf 1472 long ret;
eb38c52c 1473#ifdef CONFIG_VNC_TLS
5fb6c7a8 1474 if (vs->tls.session) {
0057a0d5
TH
1475 ret = vnc_client_read_tls(&vs->tls.session, data, datalen);
1476 } else {
0057a0d5 1477#endif /* CONFIG_VNC_TLS */
7b45a00d 1478 ret = qemu_recv(vs->csock, data, datalen, 0);
0057a0d5
TH
1479#ifdef CONFIG_VNC_TLS
1480 }
8d5d2d4c 1481#endif /* CONFIG_VNC_TLS */
23decc87 1482 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
2f9606b3
AL
1483 return vnc_client_io_error(vs, ret, socket_error());
1484}
24236869 1485
2f9606b3
AL
1486
1487/*
1488 * Called to read data from the client socket to the input buffer,
1489 * when not using any SASL SSF encryption layers. Will read as much
1490 * data as possible without blocking.
1491 *
1492 * Returns the number of bytes read. Returns -1 on error, and
1493 * disconnects the client socket.
1494 */
1495static long vnc_client_read_plain(VncState *vs)
1496{
1497 int ret;
23decc87 1498 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
2f9606b3
AL
1499 vs->input.buffer, vs->input.capacity, vs->input.offset);
1500 buffer_reserve(&vs->input, 4096);
1501 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1502 if (!ret)
1503 return 0;
24236869 1504 vs->input.offset += ret;
2f9606b3
AL
1505 return ret;
1506}
1507
175b2a6e
CC
1508static void vnc_jobs_bh(void *opaque)
1509{
1510 VncState *vs = opaque;
1511
1512 vnc_jobs_consume_buffer(vs);
1513}
2f9606b3
AL
1514
1515/*
1516 * First function called whenever there is more data to be read from
1517 * the client socket. Will delegate actual work according to whether
1518 * SASL SSF layers are enabled (thus requiring decryption calls)
1519 */
1520void vnc_client_read(void *opaque)
1521{
1522 VncState *vs = opaque;
1523 long ret;
1524
1525#ifdef CONFIG_VNC_SASL
1526 if (vs->sasl.conn && vs->sasl.runSSF)
1527 ret = vnc_client_read_sasl(vs);
1528 else
1529#endif /* CONFIG_VNC_SASL */
7536ee4b
TH
1530 if (vs->encode_ws) {
1531 ret = vnc_client_read_ws(vs);
1532 if (ret == -1) {
1533 vnc_disconnect_start(vs);
1534 return;
1535 } else if (ret == -2) {
1536 vnc_client_error(vs);
1537 return;
1538 }
8e9b0d24
DB
1539 } else {
1540 ret = vnc_client_read_plain(vs);
7536ee4b 1541 }
198a0039
GH
1542 if (!ret) {
1543 if (vs->csock == -1)
1544 vnc_disconnect_finish(vs);
28a76be8 1545 return;
198a0039 1546 }
24236869
FB
1547
1548 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
28a76be8
AL
1549 size_t len = vs->read_handler_expect;
1550 int ret;
1551
1552 ret = vs->read_handler(vs, vs->input.buffer, len);
198a0039
GH
1553 if (vs->csock == -1) {
1554 vnc_disconnect_finish(vs);
28a76be8 1555 return;
198a0039 1556 }
28a76be8
AL
1557
1558 if (!ret) {
32ed2680 1559 buffer_advance(&vs->input, len);
28a76be8
AL
1560 } else {
1561 vs->read_handler_expect = ret;
1562 }
24236869
FB
1563 }
1564}
1565
5fb6c7a8 1566void vnc_write(VncState *vs, const void *data, size_t len)
24236869
FB
1567{
1568 buffer_reserve(&vs->output, len);
1569
198a0039 1570 if (vs->csock != -1 && buffer_empty(&vs->output)) {
82e1cc4b 1571 qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs);
24236869
FB
1572 }
1573
1574 buffer_append(&vs->output, data, len);
1575}
1576
5fb6c7a8 1577void vnc_write_s32(VncState *vs, int32_t value)
24236869
FB
1578{
1579 vnc_write_u32(vs, *(uint32_t *)&value);
1580}
1581
5fb6c7a8 1582void vnc_write_u32(VncState *vs, uint32_t value)
24236869
FB
1583{
1584 uint8_t buf[4];
1585
1586 buf[0] = (value >> 24) & 0xFF;
1587 buf[1] = (value >> 16) & 0xFF;
1588 buf[2] = (value >> 8) & 0xFF;
1589 buf[3] = value & 0xFF;
1590
1591 vnc_write(vs, buf, 4);
1592}
1593
5fb6c7a8 1594void vnc_write_u16(VncState *vs, uint16_t value)
24236869 1595{
64f5a135 1596 uint8_t buf[2];
24236869
FB
1597
1598 buf[0] = (value >> 8) & 0xFF;
1599 buf[1] = value & 0xFF;
1600
1601 vnc_write(vs, buf, 2);
1602}
1603
5fb6c7a8 1604void vnc_write_u8(VncState *vs, uint8_t value)
24236869
FB
1605{
1606 vnc_write(vs, (char *)&value, 1);
1607}
1608
5fb6c7a8 1609void vnc_flush(VncState *vs)
24236869 1610{
bd023f95 1611 vnc_lock_output(vs);
8e9b0d24
DB
1612 if (vs->csock != -1 && (vs->output.offset ||
1613 vs->ws_output.offset)) {
bd023f95
CC
1614 vnc_client_write_locked(vs);
1615 }
1616 vnc_unlock_output(vs);
24236869
FB
1617}
1618
71a8cdec 1619static uint8_t read_u8(uint8_t *data, size_t offset)
24236869
FB
1620{
1621 return data[offset];
1622}
1623
71a8cdec 1624static uint16_t read_u16(uint8_t *data, size_t offset)
24236869
FB
1625{
1626 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1627}
1628
71a8cdec 1629static int32_t read_s32(uint8_t *data, size_t offset)
24236869
FB
1630{
1631 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1632 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1633}
1634
5fb6c7a8 1635uint32_t read_u32(uint8_t *data, size_t offset)
24236869
FB
1636{
1637 return ((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1638 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1639}
1640
60fe76f3 1641static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
24236869
FB
1642{
1643}
1644
9e8dd451 1645static void check_pointer_type_change(Notifier *notifier, void *data)
564c337e 1646{
37c34d9d 1647 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
14768eba 1648 int absolute = qemu_input_is_absolute();
37c34d9d 1649
29fa4ed9 1650 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
bd023f95 1651 vnc_lock_output(vs);
46a183da 1652 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
28a76be8
AL
1653 vnc_write_u8(vs, 0);
1654 vnc_write_u16(vs, 1);
1655 vnc_framebuffer_update(vs, absolute, 0,
bea60dd7
PL
1656 pixman_image_get_width(vs->vd->server),
1657 pixman_image_get_height(vs->vd->server),
29fa4ed9 1658 VNC_ENCODING_POINTER_TYPE_CHANGE);
bd023f95 1659 vnc_unlock_output(vs);
28a76be8 1660 vnc_flush(vs);
564c337e
FB
1661 }
1662 vs->absolute = absolute;
1663}
1664
24236869
FB
1665static void pointer_event(VncState *vs, int button_mask, int x, int y)
1666{
14768eba
GH
1667 static uint32_t bmap[INPUT_BUTTON_MAX] = {
1668 [INPUT_BUTTON_LEFT] = 0x01,
1669 [INPUT_BUTTON_MIDDLE] = 0x02,
1670 [INPUT_BUTTON_RIGHT] = 0x04,
1671 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1672 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1673 };
1674 QemuConsole *con = vs->vd->dcl.con;
bea60dd7
PL
1675 int width = pixman_image_get_width(vs->vd->server);
1676 int height = pixman_image_get_height(vs->vd->server);
24236869 1677
14768eba
GH
1678 if (vs->last_bmask != button_mask) {
1679 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1680 vs->last_bmask = button_mask;
1681 }
564c337e
FB
1682
1683 if (vs->absolute) {
14768eba
GH
1684 qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
1685 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
29fa4ed9 1686 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
14768eba
GH
1687 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1688 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
564c337e 1689 } else {
14768eba
GH
1690 if (vs->last_x != -1) {
1691 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1692 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1693 }
28a76be8
AL
1694 vs->last_x = x;
1695 vs->last_y = y;
24236869 1696 }
14768eba 1697 qemu_input_event_sync();
24236869
FB
1698}
1699
64f5a135
FB
1700static void reset_keys(VncState *vs)
1701{
1702 int i;
1703 for(i = 0; i < 256; i++) {
1704 if (vs->modifiers_state[i]) {
8d447d10 1705 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
64f5a135
FB
1706 vs->modifiers_state[i] = 0;
1707 }
1708 }
1709}
1710
a528b80c
AZ
1711static void press_key(VncState *vs, int keysym)
1712{
44bb61c8 1713 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
8d447d10 1714 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
2deb4acc 1715 qemu_input_event_send_key_delay(0);
8d447d10 1716 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
2deb4acc 1717 qemu_input_event_send_key_delay(0);
a528b80c
AZ
1718}
1719
ab99e5c1
LL
1720static int current_led_state(VncState *vs)
1721{
1722 int ledstate = 0;
1723
1724 if (vs->modifiers_state[0x46]) {
1725 ledstate |= QEMU_SCROLL_LOCK_LED;
1726 }
1727 if (vs->modifiers_state[0x45]) {
1728 ledstate |= QEMU_NUM_LOCK_LED;
1729 }
1730 if (vs->modifiers_state[0x3a]) {
1731 ledstate |= QEMU_CAPS_LOCK_LED;
1732 }
1733
1734 return ledstate;
1735}
1736
1737static void vnc_led_state_change(VncState *vs)
1738{
1739 int ledstate = 0;
1740
1741 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1742 return;
1743 }
1744
1745 ledstate = current_led_state(vs);
1746 vnc_lock_output(vs);
1747 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1748 vnc_write_u8(vs, 0);
1749 vnc_write_u16(vs, 1);
1750 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1751 vnc_write_u8(vs, ledstate);
1752 vnc_unlock_output(vs);
1753 vnc_flush(vs);
1754}
1755
7ffb82ca
GH
1756static void kbd_leds(void *opaque, int ledstate)
1757{
1758 VncState *vs = opaque;
96f3d174 1759 int caps, num, scr;
1483adcf 1760 bool has_changed = (ledstate != current_led_state(vs));
7ffb82ca 1761
40066175
GH
1762 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1763 (ledstate & QEMU_NUM_LOCK_LED),
1764 (ledstate & QEMU_SCROLL_LOCK_LED));
1765
7ffb82ca
GH
1766 caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
1767 num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
96f3d174 1768 scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
7ffb82ca
GH
1769
1770 if (vs->modifiers_state[0x3a] != caps) {
1771 vs->modifiers_state[0x3a] = caps;
1772 }
1773 if (vs->modifiers_state[0x45] != num) {
1774 vs->modifiers_state[0x45] = num;
1775 }
96f3d174
LL
1776 if (vs->modifiers_state[0x46] != scr) {
1777 vs->modifiers_state[0x46] = scr;
1778 }
ab99e5c1
LL
1779
1780 /* Sending the current led state message to the client */
1483adcf 1781 if (has_changed) {
ab99e5c1
LL
1782 vnc_led_state_change(vs);
1783 }
7ffb82ca
GH
1784}
1785
9ca313aa 1786static void do_key_event(VncState *vs, int down, int keycode, int sym)
24236869 1787{
64f5a135
FB
1788 /* QEMU console switch */
1789 switch(keycode) {
1790 case 0x2a: /* Left Shift */
1791 case 0x36: /* Right Shift */
1792 case 0x1d: /* Left CTRL */
1793 case 0x9d: /* Right CTRL */
1794 case 0x38: /* Left ALT */
1795 case 0xb8: /* Right ALT */
1796 if (down)
1797 vs->modifiers_state[keycode] = 1;
1798 else
1799 vs->modifiers_state[keycode] = 0;
1800 break;
5fafdf24 1801 case 0x02 ... 0x0a: /* '1' to '9' keys */
1d0d59fe
GH
1802 if (vs->vd->dcl.con == NULL &&
1803 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
64f5a135
FB
1804 /* Reset the modifiers sent to the current console */
1805 reset_keys(vs);
1806 console_select(keycode - 0x02);
1807 return;
1808 }
1809 break;
28a76be8
AL
1810 case 0x3a: /* CapsLock */
1811 case 0x45: /* NumLock */
7ffb82ca 1812 if (down)
a528b80c
AZ
1813 vs->modifiers_state[keycode] ^= 1;
1814 break;
1815 }
1816
e7b2aacc
LL
1817 /* Turn off the lock state sync logic if the client support the led
1818 state extension.
1819 */
9892088b 1820 if (down && vs->vd->lock_key_sync &&
e7b2aacc 1821 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
3a0558b5 1822 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
a528b80c
AZ
1823 /* If the numlock state needs to change then simulate an additional
1824 keypress before sending this one. This will happen if the user
1825 toggles numlock away from the VNC window.
1826 */
753b4053 1827 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
a528b80c 1828 if (!vs->modifiers_state[0x45]) {
40066175 1829 trace_vnc_key_sync_numlock(true);
a528b80c
AZ
1830 vs->modifiers_state[0x45] = 1;
1831 press_key(vs, 0xff7f);
1832 }
1833 } else {
1834 if (vs->modifiers_state[0x45]) {
40066175 1835 trace_vnc_key_sync_numlock(false);
a528b80c
AZ
1836 vs->modifiers_state[0x45] = 0;
1837 press_key(vs, 0xff7f);
1838 }
1839 }
64f5a135 1840 }
24236869 1841
9892088b 1842 if (down && vs->vd->lock_key_sync &&
e7b2aacc 1843 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
3a0558b5 1844 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
6b132502
GH
1845 /* If the capslock state needs to change then simulate an additional
1846 keypress before sending this one. This will happen if the user
1847 toggles capslock away from the VNC window.
1848 */
1849 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1850 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1851 int capslock = !!(vs->modifiers_state[0x3a]);
1852 if (capslock) {
1853 if (uppercase == shift) {
40066175 1854 trace_vnc_key_sync_capslock(false);
6b132502
GH
1855 vs->modifiers_state[0x3a] = 0;
1856 press_key(vs, 0xffe5);
1857 }
1858 } else {
1859 if (uppercase != shift) {
40066175 1860 trace_vnc_key_sync_capslock(true);
6b132502
GH
1861 vs->modifiers_state[0x3a] = 1;
1862 press_key(vs, 0xffe5);
1863 }
1864 }
1865 }
1866
81c0d5a6 1867 if (qemu_console_is_graphic(NULL)) {
8d447d10 1868 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
64f5a135 1869 } else {
e26437c2
GH
1870 bool numlock = vs->modifiers_state[0x45];
1871 bool control = (vs->modifiers_state[0x1d] ||
1872 vs->modifiers_state[0x9d]);
64f5a135
FB
1873 /* QEMU console emulation */
1874 if (down) {
1875 switch (keycode) {
1876 case 0x2a: /* Left Shift */
1877 case 0x36: /* Right Shift */
1878 case 0x1d: /* Left CTRL */
1879 case 0x9d: /* Right CTRL */
1880 case 0x38: /* Left ALT */
1881 case 0xb8: /* Right ALT */
1882 break;
1883 case 0xc8:
1884 kbd_put_keysym(QEMU_KEY_UP);
1885 break;
1886 case 0xd0:
1887 kbd_put_keysym(QEMU_KEY_DOWN);
1888 break;
1889 case 0xcb:
1890 kbd_put_keysym(QEMU_KEY_LEFT);
1891 break;
1892 case 0xcd:
1893 kbd_put_keysym(QEMU_KEY_RIGHT);
1894 break;
1895 case 0xd3:
1896 kbd_put_keysym(QEMU_KEY_DELETE);
1897 break;
1898 case 0xc7:
1899 kbd_put_keysym(QEMU_KEY_HOME);
1900 break;
1901 case 0xcf:
1902 kbd_put_keysym(QEMU_KEY_END);
1903 break;
1904 case 0xc9:
1905 kbd_put_keysym(QEMU_KEY_PAGEUP);
1906 break;
1907 case 0xd1:
1908 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1909 break;
bb0a18e1
GH
1910
1911 case 0x47:
1912 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1913 break;
1914 case 0x48:
1915 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1916 break;
1917 case 0x49:
1918 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1919 break;
1920 case 0x4b:
1921 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1922 break;
1923 case 0x4c:
1924 kbd_put_keysym('5');
1925 break;
1926 case 0x4d:
1927 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1928 break;
1929 case 0x4f:
1930 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1931 break;
1932 case 0x50:
1933 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1934 break;
1935 case 0x51:
1936 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1937 break;
1938 case 0x52:
1939 kbd_put_keysym('0');
1940 break;
1941 case 0x53:
1942 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1943 break;
1944
1945 case 0xb5:
1946 kbd_put_keysym('/');
1947 break;
1948 case 0x37:
1949 kbd_put_keysym('*');
1950 break;
1951 case 0x4a:
1952 kbd_put_keysym('-');
1953 break;
1954 case 0x4e:
1955 kbd_put_keysym('+');
1956 break;
1957 case 0x9c:
1958 kbd_put_keysym('\n');
1959 break;
1960
64f5a135 1961 default:
e26437c2
GH
1962 if (control) {
1963 kbd_put_keysym(sym & 0x1f);
1964 } else {
1965 kbd_put_keysym(sym);
1966 }
64f5a135
FB
1967 break;
1968 }
1969 }
1970 }
24236869
FB
1971}
1972
7bc9318b
GH
1973static void vnc_release_modifiers(VncState *vs)
1974{
1975 static const int keycodes[] = {
1976 /* shift, control, alt keys, both left & right */
1977 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1978 };
1979 int i, keycode;
1980
81c0d5a6 1981 if (!qemu_console_is_graphic(NULL)) {
7bc9318b
GH
1982 return;
1983 }
1984 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1985 keycode = keycodes[i];
1986 if (!vs->modifiers_state[keycode]) {
1987 continue;
1988 }
8d447d10 1989 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
7bc9318b
GH
1990 }
1991}
1992
40066175
GH
1993static const char *code2name(int keycode)
1994{
1995 return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
1996}
1997
bdbd7676
FB
1998static void key_event(VncState *vs, int down, uint32_t sym)
1999{
9ca313aa 2000 int keycode;
4a93fe17 2001 int lsym = sym;
9ca313aa 2002
81c0d5a6 2003 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
4a93fe17
GH
2004 lsym = lsym - 'A' + 'a';
2005 }
9ca313aa 2006
44bb61c8 2007 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
40066175 2008 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
9ca313aa
AL
2009 do_key_event(vs, down, keycode, sym);
2010}
2011
2012static void ext_key_event(VncState *vs, int down,
2013 uint32_t sym, uint16_t keycode)
2014{
2015 /* if the user specifies a keyboard layout, always use it */
40066175 2016 if (keyboard_layout) {
9ca313aa 2017 key_event(vs, down, sym);
40066175
GH
2018 } else {
2019 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
9ca313aa 2020 do_key_event(vs, down, keycode, sym);
40066175 2021 }
bdbd7676
FB
2022}
2023
24236869 2024static void framebuffer_update_request(VncState *vs, int incremental,
bea60dd7 2025 int x, int y, int w, int h)
24236869 2026{
bea60dd7
PL
2027 int width = pixman_image_get_width(vs->vd->server);
2028 int height = pixman_image_get_height(vs->vd->server);
cf2d385c 2029
24236869 2030 vs->need_update = 1;
bea60dd7
PL
2031
2032 if (incremental) {
2033 return;
24236869 2034 }
bea60dd7 2035
07535a89 2036 vs->force_update = 1;
bea60dd7 2037 vnc_set_area_dirty(vs->dirty, width, height, x, y, w, h);
24236869
FB
2038}
2039
9ca313aa
AL
2040static void send_ext_key_event_ack(VncState *vs)
2041{
bd023f95 2042 vnc_lock_output(vs);
46a183da 2043 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
9ca313aa
AL
2044 vnc_write_u8(vs, 0);
2045 vnc_write_u16(vs, 1);
d39fa6d8 2046 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2047 pixman_image_get_width(vs->vd->server),
2048 pixman_image_get_height(vs->vd->server),
29fa4ed9 2049 VNC_ENCODING_EXT_KEY_EVENT);
bd023f95 2050 vnc_unlock_output(vs);
9ca313aa
AL
2051 vnc_flush(vs);
2052}
2053
429a8ed3 2054static void send_ext_audio_ack(VncState *vs)
2055{
bd023f95 2056 vnc_lock_output(vs);
46a183da 2057 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
429a8ed3 2058 vnc_write_u8(vs, 0);
2059 vnc_write_u16(vs, 1);
d39fa6d8 2060 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2061 pixman_image_get_width(vs->vd->server),
2062 pixman_image_get_height(vs->vd->server),
29fa4ed9 2063 VNC_ENCODING_AUDIO);
bd023f95 2064 vnc_unlock_output(vs);
429a8ed3 2065 vnc_flush(vs);
2066}
2067
24236869
FB
2068static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2069{
2070 int i;
29fa4ed9 2071 unsigned int enc = 0;
24236869 2072
29fa4ed9 2073 vs->features = 0;
a9f20d31 2074 vs->vnc_encoding = 0;
d1af0e05
CC
2075 vs->tight.compression = 9;
2076 vs->tight.quality = -1; /* Lossless by default */
564c337e 2077 vs->absolute = -1;
24236869 2078
8a0f0d0c
CC
2079 /*
2080 * Start from the end because the encodings are sent in order of preference.
e5bed759 2081 * This way the preferred encoding (first encoding defined in the array)
8a0f0d0c
CC
2082 * will be set at the end of the loop.
2083 */
24236869 2084 for (i = n_encodings - 1; i >= 0; i--) {
29fa4ed9
AL
2085 enc = encodings[i];
2086 switch (enc) {
2087 case VNC_ENCODING_RAW:
a9f20d31 2088 vs->vnc_encoding = enc;
29fa4ed9
AL
2089 break;
2090 case VNC_ENCODING_COPYRECT:
753b4053 2091 vs->features |= VNC_FEATURE_COPYRECT_MASK;
29fa4ed9
AL
2092 break;
2093 case VNC_ENCODING_HEXTILE:
2094 vs->features |= VNC_FEATURE_HEXTILE_MASK;
a9f20d31 2095 vs->vnc_encoding = enc;
29fa4ed9 2096 break;
380282b0
CC
2097 case VNC_ENCODING_TIGHT:
2098 vs->features |= VNC_FEATURE_TIGHT_MASK;
2099 vs->vnc_encoding = enc;
2100 break;
fe3e7f2d 2101#ifdef CONFIG_VNC_PNG
efe556ad
CC
2102 case VNC_ENCODING_TIGHT_PNG:
2103 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2104 vs->vnc_encoding = enc;
2105 break;
fe3e7f2d 2106#endif
059cef40
AL
2107 case VNC_ENCODING_ZLIB:
2108 vs->features |= VNC_FEATURE_ZLIB_MASK;
a9f20d31 2109 vs->vnc_encoding = enc;
059cef40 2110 break;
148954fa
CC
2111 case VNC_ENCODING_ZRLE:
2112 vs->features |= VNC_FEATURE_ZRLE_MASK;
2113 vs->vnc_encoding = enc;
2114 break;
2115 case VNC_ENCODING_ZYWRLE:
2116 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2117 vs->vnc_encoding = enc;
2118 break;
29fa4ed9
AL
2119 case VNC_ENCODING_DESKTOPRESIZE:
2120 vs->features |= VNC_FEATURE_RESIZE_MASK;
2121 break;
2122 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2123 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2124 break;
d467b679
GH
2125 case VNC_ENCODING_RICH_CURSOR:
2126 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2127 break;
29fa4ed9 2128 case VNC_ENCODING_EXT_KEY_EVENT:
9ca313aa
AL
2129 send_ext_key_event_ack(vs);
2130 break;
29fa4ed9 2131 case VNC_ENCODING_AUDIO:
429a8ed3 2132 send_ext_audio_ack(vs);
2133 break;
29fa4ed9
AL
2134 case VNC_ENCODING_WMVi:
2135 vs->features |= VNC_FEATURE_WMVI_MASK;
ca4cca4d 2136 break;
ab99e5c1
LL
2137 case VNC_ENCODING_LED_STATE:
2138 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2139 break;
fb437313 2140 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
d1af0e05 2141 vs->tight.compression = (enc & 0x0F);
fb437313
AL
2142 break;
2143 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
b31f519e
CC
2144 if (vs->vd->lossy) {
2145 vs->tight.quality = (enc & 0x0F);
2146 }
fb437313 2147 break;
29fa4ed9
AL
2148 default:
2149 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2150 break;
2151 }
24236869 2152 }
6356e472 2153 vnc_desktop_resize(vs);
9e8dd451 2154 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
ab99e5c1 2155 vnc_led_state_change(vs);
24236869
FB
2156}
2157
6cec5487
AL
2158static void set_pixel_conversion(VncState *vs)
2159{
9f64916d
GH
2160 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2161
2162 if (fmt == VNC_SERVER_FB_FORMAT) {
6cec5487 2163 vs->write_pixels = vnc_write_pixels_copy;
70a4568f 2164 vnc_hextile_set_pixel_conversion(vs, 0);
6cec5487
AL
2165 } else {
2166 vs->write_pixels = vnc_write_pixels_generic;
70a4568f 2167 vnc_hextile_set_pixel_conversion(vs, 1);
6cec5487
AL
2168 }
2169}
2170
24236869 2171static void set_pixel_format(VncState *vs,
28a76be8
AL
2172 int bits_per_pixel, int depth,
2173 int big_endian_flag, int true_color_flag,
2174 int red_max, int green_max, int blue_max,
2175 int red_shift, int green_shift, int blue_shift)
24236869 2176{
3512779a 2177 if (!true_color_flag) {
28a76be8 2178 vnc_client_error(vs);
3512779a
FB
2179 return;
2180 }
24236869 2181
e6908bfe
PM
2182 switch (bits_per_pixel) {
2183 case 8:
2184 case 16:
2185 case 32:
2186 break;
2187 default:
2188 vnc_client_error(vs);
2189 return;
2190 }
2191
9f64916d
GH
2192 vs->client_pf.rmax = red_max;
2193 vs->client_pf.rbits = hweight_long(red_max);
2194 vs->client_pf.rshift = red_shift;
2195 vs->client_pf.rmask = red_max << red_shift;
2196 vs->client_pf.gmax = green_max;
2197 vs->client_pf.gbits = hweight_long(green_max);
2198 vs->client_pf.gshift = green_shift;
2199 vs->client_pf.gmask = green_max << green_shift;
2200 vs->client_pf.bmax = blue_max;
2201 vs->client_pf.bbits = hweight_long(blue_max);
2202 vs->client_pf.bshift = blue_shift;
2203 vs->client_pf.bmask = blue_max << blue_shift;
2204 vs->client_pf.bits_per_pixel = bits_per_pixel;
2205 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2206 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2207 vs->client_be = big_endian_flag;
6cec5487
AL
2208
2209 set_pixel_conversion(vs);
24236869 2210
1d0d59fe
GH
2211 graphic_hw_invalidate(vs->vd->dcl.con);
2212 graphic_hw_update(vs->vd->dcl.con);
24236869
FB
2213}
2214
ca4cca4d
AL
2215static void pixel_format_message (VncState *vs) {
2216 char pad[3] = { 0, 0, 0 };
2217
9f64916d
GH
2218 vs->client_pf = qemu_default_pixelformat(32);
2219
2220 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2221 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
ca4cca4d 2222
e2542fe2 2223#ifdef HOST_WORDS_BIGENDIAN
ca4cca4d
AL
2224 vnc_write_u8(vs, 1); /* big-endian-flag */
2225#else
2226 vnc_write_u8(vs, 0); /* big-endian-flag */
2227#endif
2228 vnc_write_u8(vs, 1); /* true-color-flag */
9f64916d
GH
2229 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2230 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2231 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2232 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2233 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2234 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2235 vnc_write(vs, pad, 3); /* padding */
70a4568f
CC
2236
2237 vnc_hextile_set_pixel_conversion(vs, 0);
ca4cca4d 2238 vs->write_pixels = vnc_write_pixels_copy;
ca4cca4d
AL
2239}
2240
753b4053 2241static void vnc_colordepth(VncState *vs)
7eac3a87 2242{
753b4053 2243 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
ca4cca4d 2244 /* Sending a WMVi message to notify the client*/
bd023f95 2245 vnc_lock_output(vs);
46a183da 2246 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
ca4cca4d
AL
2247 vnc_write_u8(vs, 0);
2248 vnc_write_u16(vs, 1); /* number of rects */
d39fa6d8 2249 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2250 pixman_image_get_width(vs->vd->server),
2251 pixman_image_get_height(vs->vd->server),
d39fa6d8 2252 VNC_ENCODING_WMVi);
ca4cca4d 2253 pixel_format_message(vs);
bd023f95 2254 vnc_unlock_output(vs);
ca4cca4d 2255 vnc_flush(vs);
7eac3a87 2256 } else {
6cec5487 2257 set_pixel_conversion(vs);
7eac3a87
AL
2258 }
2259}
2260
60fe76f3 2261static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
24236869
FB
2262{
2263 int i;
2264 uint16_t limit;
2430ffe4
SS
2265 VncDisplay *vd = vs->vd;
2266
2267 if (data[0] > 3) {
0f7b2864 2268 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2430ffe4 2269 }
24236869
FB
2270
2271 switch (data[0]) {
46a183da 2272 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
28a76be8
AL
2273 if (len == 1)
2274 return 20;
2275
2276 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
2277 read_u8(data, 6), read_u8(data, 7),
2278 read_u16(data, 8), read_u16(data, 10),
2279 read_u16(data, 12), read_u8(data, 14),
2280 read_u8(data, 15), read_u8(data, 16));
2281 break;
46a183da 2282 case VNC_MSG_CLIENT_SET_ENCODINGS:
28a76be8
AL
2283 if (len == 1)
2284 return 4;
24236869 2285
28a76be8 2286 if (len == 4) {
69dd5c9f
AL
2287 limit = read_u16(data, 2);
2288 if (limit > 0)
2289 return 4 + (limit * 4);
2290 } else
2291 limit = read_u16(data, 2);
24236869 2292
28a76be8
AL
2293 for (i = 0; i < limit; i++) {
2294 int32_t val = read_s32(data, 4 + (i * 4));
2295 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2296 }
24236869 2297
28a76be8
AL
2298 set_encodings(vs, (int32_t *)(data + 4), limit);
2299 break;
46a183da 2300 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
28a76be8
AL
2301 if (len == 1)
2302 return 10;
24236869 2303
28a76be8
AL
2304 framebuffer_update_request(vs,
2305 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2306 read_u16(data, 6), read_u16(data, 8));
2307 break;
46a183da 2308 case VNC_MSG_CLIENT_KEY_EVENT:
28a76be8
AL
2309 if (len == 1)
2310 return 8;
24236869 2311
28a76be8
AL
2312 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2313 break;
46a183da 2314 case VNC_MSG_CLIENT_POINTER_EVENT:
28a76be8
AL
2315 if (len == 1)
2316 return 6;
24236869 2317
28a76be8
AL
2318 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2319 break;
46a183da 2320 case VNC_MSG_CLIENT_CUT_TEXT:
f9a70e79 2321 if (len == 1) {
28a76be8 2322 return 8;
f9a70e79 2323 }
28a76be8 2324 if (len == 8) {
baa7666c 2325 uint32_t dlen = read_u32(data, 4);
f9a70e79
PL
2326 if (dlen > (1 << 20)) {
2327 error_report("vnc: client_cut_text msg payload has %u bytes"
2328 " which exceeds our limit of 1MB.", dlen);
2329 vnc_client_error(vs);
2330 break;
2331 }
2332 if (dlen > 0) {
baa7666c 2333 return 8 + dlen;
f9a70e79 2334 }
baa7666c 2335 }
24236869 2336
28a76be8
AL
2337 client_cut_text(vs, read_u32(data, 4), data + 8);
2338 break;
46a183da 2339 case VNC_MSG_CLIENT_QEMU:
9ca313aa
AL
2340 if (len == 1)
2341 return 2;
2342
2343 switch (read_u8(data, 1)) {
46a183da 2344 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
9ca313aa
AL
2345 if (len == 2)
2346 return 12;
2347
2348 ext_key_event(vs, read_u16(data, 2),
2349 read_u32(data, 4), read_u32(data, 8));
2350 break;
46a183da 2351 case VNC_MSG_CLIENT_QEMU_AUDIO:
429a8ed3 2352 if (len == 2)
2353 return 4;
2354
2355 switch (read_u16 (data, 2)) {
46a183da 2356 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
429a8ed3 2357 audio_add(vs);
2358 break;
46a183da 2359 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
429a8ed3 2360 audio_del(vs);
2361 break;
46a183da 2362 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
429a8ed3 2363 if (len == 4)
2364 return 10;
2365 switch (read_u8(data, 4)) {
2366 case 0: vs->as.fmt = AUD_FMT_U8; break;
2367 case 1: vs->as.fmt = AUD_FMT_S8; break;
2368 case 2: vs->as.fmt = AUD_FMT_U16; break;
2369 case 3: vs->as.fmt = AUD_FMT_S16; break;
2370 case 4: vs->as.fmt = AUD_FMT_U32; break;
2371 case 5: vs->as.fmt = AUD_FMT_S32; break;
2372 default:
153130cd 2373 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
429a8ed3 2374 vnc_client_error(vs);
2375 break;
2376 }
2377 vs->as.nchannels = read_u8(data, 5);
2378 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
153130cd
DB
2379 VNC_DEBUG("Invalid audio channel coount %d\n",
2380 read_u8(data, 5));
429a8ed3 2381 vnc_client_error(vs);
2382 break;
2383 }
2384 vs->as.freq = read_u32(data, 6);
2385 break;
2386 default:
153130cd 2387 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
429a8ed3 2388 vnc_client_error(vs);
2389 break;
2390 }
2391 break;
2392
9ca313aa 2393 default:
153130cd 2394 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
9ca313aa
AL
2395 vnc_client_error(vs);
2396 break;
2397 }
2398 break;
24236869 2399 default:
153130cd 2400 VNC_DEBUG("Msg: %d\n", data[0]);
28a76be8
AL
2401 vnc_client_error(vs);
2402 break;
24236869 2403 }
5fafdf24 2404
24236869
FB
2405 vnc_read_when(vs, protocol_client_msg, 1);
2406 return 0;
2407}
2408
60fe76f3 2409static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869 2410{
c35734b2 2411 char buf[1024];
8cf36489 2412 VncShareMode mode;
c35734b2 2413 int size;
24236869 2414
8cf36489
GH
2415 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2416 switch (vs->vd->share_policy) {
2417 case VNC_SHARE_POLICY_IGNORE:
2418 /*
2419 * Ignore the shared flag. Nothing to do here.
2420 *
2421 * Doesn't conform to the rfb spec but is traditional qemu
2422 * behavior, thus left here as option for compatibility
2423 * reasons.
2424 */
2425 break;
2426 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2427 /*
2428 * Policy: Allow clients ask for exclusive access.
2429 *
2430 * Implementation: When a client asks for exclusive access,
2431 * disconnect all others. Shared connects are allowed as long
2432 * as no exclusive connection exists.
2433 *
2434 * This is how the rfb spec suggests to handle the shared flag.
2435 */
2436 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2437 VncState *client;
2438 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2439 if (vs == client) {
2440 continue;
2441 }
2442 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2443 client->share_mode != VNC_SHARE_MODE_SHARED) {
2444 continue;
2445 }
2446 vnc_disconnect_start(client);
2447 }
2448 }
2449 if (mode == VNC_SHARE_MODE_SHARED) {
2450 if (vs->vd->num_exclusive > 0) {
2451 vnc_disconnect_start(vs);
2452 return 0;
2453 }
2454 }
2455 break;
2456 case VNC_SHARE_POLICY_FORCE_SHARED:
2457 /*
2458 * Policy: Shared connects only.
2459 * Implementation: Disallow clients asking for exclusive access.
2460 *
2461 * Useful for shared desktop sessions where you don't want
2462 * someone forgetting to say -shared when running the vnc
2463 * client disconnect everybody else.
2464 */
2465 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2466 vnc_disconnect_start(vs);
2467 return 0;
2468 }
2469 break;
2470 }
2471 vnc_set_share_mode(vs, mode);
2472
e5f34cdd
GH
2473 if (vs->vd->num_shared > vs->vd->connections_limit) {
2474 vnc_disconnect_start(vs);
2475 return 0;
2476 }
2477
bea60dd7
PL
2478 vs->client_width = pixman_image_get_width(vs->vd->server);
2479 vs->client_height = pixman_image_get_height(vs->vd->server);
5862d195
GH
2480 vnc_write_u16(vs, vs->client_width);
2481 vnc_write_u16(vs, vs->client_height);
24236869 2482
ca4cca4d 2483 pixel_format_message(vs);
24236869 2484
c35734b2
TS
2485 if (qemu_name)
2486 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2487 else
2488 size = snprintf(buf, sizeof(buf), "QEMU");
2489
2490 vnc_write_u32(vs, size);
2491 vnc_write(vs, buf, size);
24236869
FB
2492 vnc_flush(vs);
2493
4a80dba3 2494 vnc_client_cache_auth(vs);
fb6ba0d5 2495 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
4a80dba3 2496
24236869
FB
2497 vnc_read_when(vs, protocol_client_msg, 1);
2498
2499 return 0;
2500}
2501
5fb6c7a8
AL
2502void start_client_init(VncState *vs)
2503{
2504 vnc_read_when(vs, protocol_client_init, 1);
2505}
2506
70848515
TS
2507static void make_challenge(VncState *vs)
2508{
2509 int i;
2510
2511 srand(time(NULL)+getpid()+getpid()*987654+rand());
2512
2513 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2514 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2515}
2516
60fe76f3 2517static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 2518{
60fe76f3 2519 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
800567a6 2520 size_t i, pwlen;
60fe76f3 2521 unsigned char key[8];
3c9405a0 2522 time_t now = time(NULL);
800567a6
DB
2523 QCryptoCipher *cipher;
2524 Error *err = NULL;
70848515 2525
1cd20f8b 2526 if (!vs->vd->password) {
28a76be8 2527 VNC_DEBUG("No password configured on server");
6bffdf0f 2528 goto reject;
70848515 2529 }
3c9405a0
GH
2530 if (vs->vd->expires < now) {
2531 VNC_DEBUG("Password is expired");
2532 goto reject;
2533 }
70848515
TS
2534
2535 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2536
2537 /* Calculate the expected challenge response */
753b4053 2538 pwlen = strlen(vs->vd->password);
70848515 2539 for (i=0; i<sizeof(key); i++)
753b4053 2540 key[i] = i<pwlen ? vs->vd->password[i] : 0;
800567a6
DB
2541
2542 cipher = qcrypto_cipher_new(
2543 QCRYPTO_CIPHER_ALG_DES_RFB,
2544 QCRYPTO_CIPHER_MODE_ECB,
2545 key, G_N_ELEMENTS(key),
2546 &err);
2547 if (!cipher) {
2548 VNC_DEBUG("Cannot initialize cipher %s",
2549 error_get_pretty(err));
2550 error_free(err);
2551 goto reject;
2552 }
2553
a1695137 2554 if (qcrypto_cipher_encrypt(cipher,
800567a6
DB
2555 vs->challenge,
2556 response,
2557 VNC_AUTH_CHALLENGE_SIZE,
2558 &err) < 0) {
2559 VNC_DEBUG("Cannot encrypt challenge %s",
2560 error_get_pretty(err));
2561 error_free(err);
2562 goto reject;
2563 }
70848515
TS
2564
2565 /* Compare expected vs actual challenge response */
2566 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
e5bed759 2567 VNC_DEBUG("Client challenge response did not match\n");
6bffdf0f 2568 goto reject;
70848515 2569 } else {
28a76be8
AL
2570 VNC_DEBUG("Accepting VNC challenge response\n");
2571 vnc_write_u32(vs, 0); /* Accept auth */
2572 vnc_flush(vs);
70848515 2573
5fb6c7a8 2574 start_client_init(vs);
70848515
TS
2575 }
2576 return 0;
6bffdf0f
GH
2577
2578reject:
2579 vnc_write_u32(vs, 1); /* Reject auth */
2580 if (vs->minor >= 8) {
2581 static const char err[] = "Authentication failed";
2582 vnc_write_u32(vs, sizeof(err));
2583 vnc_write(vs, err, sizeof(err));
2584 }
2585 vnc_flush(vs);
2586 vnc_client_error(vs);
2587 return 0;
70848515
TS
2588}
2589
5fb6c7a8 2590void start_auth_vnc(VncState *vs)
70848515
TS
2591{
2592 make_challenge(vs);
2593 /* Send client a 'random' challenge */
2594 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2595 vnc_flush(vs);
2596
2597 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
469b15c6
TS
2598}
2599
2600
60fe76f3 2601static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
2602{
2603 /* We only advertise 1 auth scheme at a time, so client
2604 * must pick the one we sent. Verify this */
7e7e2ebc 2605 if (data[0] != vs->auth) { /* Reject auth */
1263b7d6 2606 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
70848515
TS
2607 vnc_write_u32(vs, 1);
2608 if (vs->minor >= 8) {
2609 static const char err[] = "Authentication failed";
2610 vnc_write_u32(vs, sizeof(err));
2611 vnc_write(vs, err, sizeof(err));
2612 }
2613 vnc_client_error(vs);
2614 } else { /* Accept requested auth */
2615 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
7e7e2ebc 2616 switch (vs->auth) {
70848515
TS
2617 case VNC_AUTH_NONE:
2618 VNC_DEBUG("Accept auth none\n");
a26c97ad
AZ
2619 if (vs->minor >= 8) {
2620 vnc_write_u32(vs, 0); /* Accept auth completion */
2621 vnc_flush(vs);
2622 }
5fb6c7a8 2623 start_client_init(vs);
70848515
TS
2624 break;
2625
2626 case VNC_AUTH_VNC:
2627 VNC_DEBUG("Start VNC auth\n");
5fb6c7a8
AL
2628 start_auth_vnc(vs);
2629 break;
70848515 2630
eb38c52c 2631#ifdef CONFIG_VNC_TLS
8d5d2d4c 2632 case VNC_AUTH_VENCRYPT:
3a93113a 2633 VNC_DEBUG("Accept VeNCrypt auth\n");
5fb6c7a8
AL
2634 start_auth_vencrypt(vs);
2635 break;
8d5d2d4c
TS
2636#endif /* CONFIG_VNC_TLS */
2637
2f9606b3
AL
2638#ifdef CONFIG_VNC_SASL
2639 case VNC_AUTH_SASL:
2640 VNC_DEBUG("Accept SASL auth\n");
2641 start_auth_sasl(vs);
2642 break;
2643#endif /* CONFIG_VNC_SASL */
2644
70848515 2645 default: /* Should not be possible, but just in case */
7e7e2ebc 2646 VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
70848515
TS
2647 vnc_write_u8(vs, 1);
2648 if (vs->minor >= 8) {
2649 static const char err[] = "Authentication failed";
2650 vnc_write_u32(vs, sizeof(err));
2651 vnc_write(vs, err, sizeof(err));
2652 }
2653 vnc_client_error(vs);
2654 }
2655 }
2656 return 0;
2657}
2658
60fe76f3 2659static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
2660{
2661 char local[13];
24236869
FB
2662
2663 memcpy(local, version, 12);
2664 local[12] = 0;
2665
70848515 2666 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
28a76be8
AL
2667 VNC_DEBUG("Malformed protocol version %s\n", local);
2668 vnc_client_error(vs);
2669 return 0;
24236869 2670 }
70848515
TS
2671 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2672 if (vs->major != 3 ||
28a76be8
AL
2673 (vs->minor != 3 &&
2674 vs->minor != 4 &&
2675 vs->minor != 5 &&
2676 vs->minor != 7 &&
2677 vs->minor != 8)) {
2678 VNC_DEBUG("Unsupported client version\n");
2679 vnc_write_u32(vs, VNC_AUTH_INVALID);
2680 vnc_flush(vs);
2681 vnc_client_error(vs);
2682 return 0;
70848515 2683 }
b0566f4f 2684 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
2685 * as equivalent to v3.3 by servers
2686 */
b0566f4f 2687 if (vs->minor == 4 || vs->minor == 5)
28a76be8 2688 vs->minor = 3;
70848515
TS
2689
2690 if (vs->minor == 3) {
7e7e2ebc 2691 if (vs->auth == VNC_AUTH_NONE) {
70848515 2692 VNC_DEBUG("Tell client auth none\n");
7e7e2ebc 2693 vnc_write_u32(vs, vs->auth);
70848515 2694 vnc_flush(vs);
28a76be8 2695 start_client_init(vs);
7e7e2ebc 2696 } else if (vs->auth == VNC_AUTH_VNC) {
70848515 2697 VNC_DEBUG("Tell client VNC auth\n");
7e7e2ebc 2698 vnc_write_u32(vs, vs->auth);
70848515
TS
2699 vnc_flush(vs);
2700 start_auth_vnc(vs);
2701 } else {
7e7e2ebc 2702 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
70848515
TS
2703 vnc_write_u32(vs, VNC_AUTH_INVALID);
2704 vnc_flush(vs);
2705 vnc_client_error(vs);
2706 }
2707 } else {
7e7e2ebc 2708 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
28a76be8 2709 vnc_write_u8(vs, 1); /* num auth */
7e7e2ebc 2710 vnc_write_u8(vs, vs->auth);
28a76be8
AL
2711 vnc_read_when(vs, protocol_client_auth, 1);
2712 vnc_flush(vs);
70848515 2713 }
24236869
FB
2714
2715 return 0;
2716}
2717
999342a0
CC
2718static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2719{
2720 struct VncSurface *vs = &vd->guest;
2721
2722 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2723}
2724
7d964c9d
CC
2725void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2726{
2727 int i, j;
2728
2729 w = (x + w) / VNC_STAT_RECT;
2730 h = (y + h) / VNC_STAT_RECT;
2731 x /= VNC_STAT_RECT;
2732 y /= VNC_STAT_RECT;
2733
207f328a
CC
2734 for (j = y; j <= h; j++) {
2735 for (i = x; i <= w; i++) {
7d964c9d
CC
2736 vs->lossy_rect[j][i] = 1;
2737 }
2738 }
2739}
2740
2741static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2742{
2743 VncState *vs;
2744 int sty = y / VNC_STAT_RECT;
2745 int stx = x / VNC_STAT_RECT;
2746 int has_dirty = 0;
2747
2748 y = y / VNC_STAT_RECT * VNC_STAT_RECT;
2749 x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2750
2751 QTAILQ_FOREACH(vs, &vd->clients, next) {
bc2429b9 2752 int j;
7d964c9d
CC
2753
2754 /* kernel send buffers are full -> refresh later */
2755 if (vs->output.offset) {
2756 continue;
2757 }
2758
2759 if (!vs->lossy_rect[sty][stx]) {
2760 continue;
2761 }
207f328a 2762
7d964c9d
CC
2763 vs->lossy_rect[sty][stx] = 0;
2764 for (j = 0; j < VNC_STAT_RECT; ++j) {
b4c85ddc
PL
2765 bitmap_set(vs->dirty[y + j],
2766 x / VNC_DIRTY_PIXELS_PER_BIT,
2767 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
7d964c9d
CC
2768 }
2769 has_dirty++;
2770 }
207f328a 2771
7d964c9d
CC
2772 return has_dirty;
2773}
2774
2775static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
999342a0 2776{
9f64916d
GH
2777 int width = pixman_image_get_width(vd->guest.fb);
2778 int height = pixman_image_get_height(vd->guest.fb);
999342a0
CC
2779 int x, y;
2780 struct timeval res;
7d964c9d 2781 int has_dirty = 0;
999342a0 2782
9f64916d
GH
2783 for (y = 0; y < height; y += VNC_STAT_RECT) {
2784 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
2785 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2786
2787 rect->updated = false;
2788 }
2789 }
2790
ad620c29 2791 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
999342a0
CC
2792
2793 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
7d964c9d 2794 return has_dirty;
999342a0
CC
2795 }
2796 vd->guest.last_freq_check = *tv;
2797
9f64916d
GH
2798 for (y = 0; y < height; y += VNC_STAT_RECT) {
2799 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
2800 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2801 int count = ARRAY_SIZE(rect->times);
2802 struct timeval min, max;
2803
2804 if (!timerisset(&rect->times[count - 1])) {
2805 continue ;
2806 }
2807
2808 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 2809 qemu_timersub(tv, &max, &res);
999342a0
CC
2810
2811 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2812 rect->freq = 0;
7d964c9d 2813 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
999342a0
CC
2814 memset(rect->times, 0, sizeof (rect->times));
2815 continue ;
2816 }
2817
2818 min = rect->times[rect->idx];
2819 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 2820 qemu_timersub(&max, &min, &res);
999342a0
CC
2821
2822 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2823 rect->freq /= count;
2824 rect->freq = 1. / rect->freq;
2825 }
2826 }
7d964c9d 2827 return has_dirty;
999342a0
CC
2828}
2829
2830double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2831{
2832 int i, j;
2833 double total = 0;
2834 int num = 0;
2835
2836 x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
2837 y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
2838
2839 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2840 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2841 total += vnc_stat_rect(vs->vd, i, j)->freq;
2842 num++;
2843 }
2844 }
2845
2846 if (num) {
2847 return total / num;
2848 } else {
2849 return 0;
2850 }
2851}
2852
2853static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2854{
2855 VncRectStat *rect;
2856
2857 rect = vnc_stat_rect(vd, x, y);
2858 if (rect->updated) {
2859 return ;
2860 }
2861 rect->times[rect->idx] = *tv;
2862 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2863 rect->updated = true;
2864}
2865
1fc62412
SS
2866static int vnc_refresh_server_surface(VncDisplay *vd)
2867{
bea60dd7
PL
2868 int width = MIN(pixman_image_get_width(vd->guest.fb),
2869 pixman_image_get_width(vd->server));
2870 int height = MIN(pixman_image_get_height(vd->guest.fb),
2871 pixman_image_get_height(vd->server));
2872 int cmp_bytes, server_stride, min_stride, guest_stride, y = 0;
12b316d4 2873 uint8_t *guest_row0 = NULL, *server_row0;
41b4bef6 2874 VncState *vs;
1fc62412 2875 int has_dirty = 0;
9f64916d 2876 pixman_image_t *tmpbuf = NULL;
1fc62412 2877
80e0c8c3 2878 struct timeval tv = { 0, 0 };
999342a0 2879
80e0c8c3
CC
2880 if (!vd->non_adaptive) {
2881 gettimeofday(&tv, NULL);
2882 has_dirty = vnc_update_stats(vd, &tv);
2883 }
999342a0 2884
1fc62412
SS
2885 /*
2886 * Walk through the guest dirty map.
2887 * Check and copy modified bits from guest to server surface.
2888 * Update server dirty map.
2889 */
bea60dd7
PL
2890 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
2891 server_stride = guest_stride = pixman_image_get_stride(vd->server);
2892 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2893 server_stride);
9f64916d
GH
2894 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2895 int width = pixman_image_get_width(vd->server);
2896 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
12b316d4
PL
2897 } else {
2898 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2899 guest_stride = pixman_image_get_stride(vd->guest.fb);
2900 }
bea60dd7 2901 min_stride = MIN(server_stride, guest_stride);
12b316d4 2902
12b316d4
PL
2903 for (;;) {
2904 int x;
2905 uint8_t *guest_ptr, *server_ptr;
2906 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2907 height * VNC_DIRTY_BPL(&vd->guest),
2908 y * VNC_DIRTY_BPL(&vd->guest));
2909 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2910 /* no more dirty bits */
2911 break;
2912 }
2913 y = offset / VNC_DIRTY_BPL(&vd->guest);
2914 x = offset % VNC_DIRTY_BPL(&vd->guest);
1fc62412 2915
12b316d4
PL
2916 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2917
2918 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2919 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2920 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2921 } else {
2922 guest_ptr = guest_row0 + y * guest_stride;
2923 }
2924 guest_ptr += x * cmp_bytes;
2925
2926 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2927 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
bea60dd7 2928 int _cmp_bytes = cmp_bytes;
12b316d4
PL
2929 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2930 continue;
2931 }
bea60dd7
PL
2932 if ((x + 1) * cmp_bytes > min_stride) {
2933 _cmp_bytes = min_stride - x * cmp_bytes;
2934 }
2935 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
12b316d4
PL
2936 continue;
2937 }
bea60dd7 2938 memcpy(server_ptr, guest_ptr, _cmp_bytes);
12b316d4
PL
2939 if (!vd->non_adaptive) {
2940 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2941 y, &tv);
1fc62412 2942 }
12b316d4
PL
2943 QTAILQ_FOREACH(vs, &vd->clients, next) {
2944 set_bit(x, vs->dirty[y]);
2945 }
2946 has_dirty++;
1fc62412 2947 }
12b316d4
PL
2948
2949 y++;
1fc62412 2950 }
9f64916d 2951 qemu_pixman_image_unref(tmpbuf);
1fc62412
SS
2952 return has_dirty;
2953}
2954
0f7b2864 2955static void vnc_refresh(DisplayChangeListener *dcl)
703bc68f 2956{
0f7b2864 2957 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
41b4bef6
AS
2958 VncState *vs, *vn;
2959 int has_dirty, rects = 0;
703bc68f 2960
9d6b2070
C
2961 if (QTAILQ_EMPTY(&vd->clients)) {
2962 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2963 return;
2964 }
2965
1d0d59fe 2966 graphic_hw_update(vd->dcl.con);
703bc68f 2967
bd023f95 2968 if (vnc_trylock_display(vd)) {
0f7b2864 2969 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
bd023f95
CC
2970 return;
2971 }
2972
1fc62412 2973 has_dirty = vnc_refresh_server_surface(vd);
bd023f95 2974 vnc_unlock_display(vd);
1fc62412 2975
41b4bef6 2976 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
38ee14f4 2977 rects += vnc_update_client(vs, has_dirty, false);
6185c578 2978 /* vs might be free()ed here */
703bc68f 2979 }
bd023f95 2980
2430ffe4 2981 if (has_dirty && rects) {
0f7b2864
GH
2982 vd->dcl.update_interval /= 2;
2983 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
2984 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
2985 }
2430ffe4 2986 } else {
0f7b2864
GH
2987 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
2988 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
2989 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
2990 }
703bc68f
SS
2991 }
2992}
2993
2c8cf549
MT
2994static void vnc_connect(VncDisplay *vd, int csock,
2995 bool skipauth, bool websocket)
3aa3eea3 2996{
7267c094 2997 VncState *vs = g_malloc0(sizeof(VncState));
7d964c9d
CC
2998 int i;
2999
753b4053 3000 vs->csock = csock;
d616ccc5 3001 vs->vd = vd;
7e7e2ebc
DB
3002
3003 if (skipauth) {
3004 vs->auth = VNC_AUTH_NONE;
7e7e2ebc 3005 vs->subauth = VNC_AUTH_INVALID;
7e7e2ebc 3006 } else {
f9148c8a
DB
3007 if (websocket) {
3008 vs->auth = vd->ws_auth;
3009 vs->subauth = VNC_AUTH_INVALID;
3010 } else {
3011 vs->auth = vd->auth;
3012 vs->subauth = vd->subauth;
3013 }
7e7e2ebc 3014 }
f9148c8a
DB
3015 VNC_DEBUG("Client sock=%d ws=%d auth=%d subauth=%d\n",
3016 csock, websocket, vs->auth, vs->subauth);
7e7e2ebc 3017
7267c094 3018 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
7d964c9d 3019 for (i = 0; i < VNC_STAT_ROWS; ++i) {
7267c094 3020 vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));
7d964c9d 3021 }
753b4053
AL
3022
3023 VNC_DEBUG("New client on socket %d\n", csock);
0f7b2864 3024 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
f9e8cacc 3025 qemu_set_nonblock(vs->csock);
7536ee4b
TH
3026 if (websocket) {
3027 vs->websocket = 1;
0057a0d5 3028#ifdef CONFIG_VNC_TLS
f9148c8a 3029 if (vd->ws_tls) {
82e1cc4b 3030 qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io, NULL, vs);
0057a0d5
TH
3031 } else
3032#endif /* CONFIG_VNC_TLS */
3033 {
82e1cc4b 3034 qemu_set_fd_handler(vs->csock, vncws_handshake_read, NULL, vs);
0057a0d5 3035 }
7536ee4b 3036 } else
7536ee4b 3037 {
82e1cc4b 3038 qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
7536ee4b 3039 }
753b4053 3040
4a80dba3 3041 vnc_client_cache_addr(vs);
fb6ba0d5 3042 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
8cf36489 3043 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
4a80dba3 3044
8e9b0d24 3045 if (!vs->websocket) {
7536ee4b
TH
3046 vnc_init_state(vs);
3047 }
e5f34cdd
GH
3048
3049 if (vd->num_connecting > vd->connections_limit) {
3050 QTAILQ_FOREACH(vs, &vd->clients, next) {
3051 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3052 vnc_disconnect_start(vs);
3053 return;
3054 }
3055 }
3056 }
7536ee4b
TH
3057}
3058
3059void vnc_init_state(VncState *vs)
3060{
6fd8e79a 3061 vs->initialized = true;
7536ee4b
TH
3062 VncDisplay *vd = vs->vd;
3063
753b4053
AL
3064 vs->last_x = -1;
3065 vs->last_y = -1;
3066
3067 vs->as.freq = 44100;
3068 vs->as.nchannels = 2;
3069 vs->as.fmt = AUD_FMT_S16;
3070 vs->as.endianness = 0;
3071
bd023f95 3072 qemu_mutex_init(&vs->output_mutex);
175b2a6e 3073 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
bd023f95 3074
e5f34cdd 3075 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
1fc62412 3076
1d0d59fe 3077 graphic_hw_update(vd->dcl.con);
1fc62412 3078
3aa3eea3
AZ
3079 vnc_write(vs, "RFB 003.008\n", 12);
3080 vnc_flush(vs);
3081 vnc_read_when(vs, protocol_version, 12);
53762ddb 3082 reset_keys(vs);
3a0558b5
GH
3083 if (vs->vd->lock_key_sync)
3084 vs->led = qemu_add_led_event_handler(kbd_leds, vs);
753b4053 3085
37c34d9d
AL
3086 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3087 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3088
198a0039 3089 /* vs might be free()ed here */
3aa3eea3
AZ
3090}
3091
7536ee4b 3092static void vnc_listen_read(void *opaque, bool websocket)
24236869 3093{
753b4053 3094 VncDisplay *vs = opaque;
24236869
FB
3095 struct sockaddr_in addr;
3096 socklen_t addrlen = sizeof(addr);
7536ee4b 3097 int csock;
24236869 3098
9f60ad50 3099 /* Catch-up */
1d0d59fe 3100 graphic_hw_update(vs->dcl.con);
7536ee4b
TH
3101 if (websocket) {
3102 csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
8e9b0d24 3103 } else {
7536ee4b
TH
3104 csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
3105 }
9f60ad50 3106
753b4053 3107 if (csock != -1) {
86152436 3108 socket_set_nodelay(csock);
2c8cf549 3109 vnc_connect(vs, csock, false, websocket);
24236869
FB
3110 }
3111}
3112
7536ee4b
TH
3113static void vnc_listen_regular_read(void *opaque)
3114{
2c8cf549 3115 vnc_listen_read(opaque, false);
7536ee4b
TH
3116}
3117
7536ee4b
TH
3118static void vnc_listen_websocket_read(void *opaque)
3119{
2c8cf549 3120 vnc_listen_read(opaque, true);
7536ee4b 3121}
7536ee4b 3122
7c20b4a3 3123static const DisplayChangeListenerOps dcl_ops = {
34da30af
BH
3124 .dpy_name = "vnc",
3125 .dpy_refresh = vnc_refresh,
3126 .dpy_gfx_copy = vnc_dpy_copy,
3127 .dpy_gfx_update = vnc_dpy_update,
3128 .dpy_gfx_switch = vnc_dpy_switch,
3129 .dpy_gfx_check_format = qemu_pixman_check_format,
3130 .dpy_mouse_set = vnc_mouse_set,
3131 .dpy_cursor_define = vnc_dpy_cursor_define,
7c20b4a3
GH
3132};
3133
14f7143e 3134void vnc_display_init(const char *id)
24236869 3135{
4db14629
GH
3136 VncDisplay *vs;
3137
3138 if (vnc_display_find(id) != NULL) {
3139 return;
3140 }
3141 vs = g_malloc0(sizeof(*vs));
24236869 3142
14f7143e 3143 vs->id = strdup(id);
d616ccc5 3144 QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
24236869
FB
3145
3146 vs->lsock = -1;
7536ee4b 3147 vs->lwebsock = -1;
24236869 3148
41b4bef6 3149 QTAILQ_INIT(&vs->clients);
3c9405a0 3150 vs->expires = TIME_MAX;
24236869 3151
40066175
GH
3152 if (keyboard_layout) {
3153 trace_vnc_key_map_init(keyboard_layout);
0483755a 3154 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
40066175 3155 } else {
0483755a 3156 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
40066175 3157 }
24236869 3158
24236869 3159 if (!vs->kbd_layout)
28a76be8 3160 exit(1);
24236869 3161
bd023f95
CC
3162 qemu_mutex_init(&vs->mutex);
3163 vnc_start_worker_thread();
bd023f95 3164
21ef45d7 3165 vs->dcl.ops = &dcl_ops;
5209089f 3166 register_displaychangelistener(&vs->dcl);
71cab5ca
TS
3167}
3168
6f43024c 3169
14f7143e 3170static void vnc_display_close(VncDisplay *vs)
71cab5ca 3171{
452b4d88
AL
3172 if (!vs)
3173 return;
bf7aa45e
GH
3174 vs->enabled = false;
3175 vs->is_unix = false;
71cab5ca 3176 if (vs->lsock != -1) {
82e1cc4b 3177 qemu_set_fd_handler(vs->lsock, NULL, NULL, NULL);
28a76be8
AL
3178 close(vs->lsock);
3179 vs->lsock = -1;
71cab5ca 3180 }
bf7aa45e 3181 vs->ws_enabled = false;
7536ee4b 3182 if (vs->lwebsock != -1) {
82e1cc4b 3183 qemu_set_fd_handler(vs->lwebsock, NULL, NULL, NULL);
7536ee4b
TH
3184 close(vs->lwebsock);
3185 vs->lwebsock = -1;
3186 }
70848515 3187 vs->auth = VNC_AUTH_INVALID;
8d5d2d4c 3188 vs->subauth = VNC_AUTH_INVALID;
d169f04b 3189#ifdef CONFIG_VNC_TLS
5fb6c7a8 3190 vs->tls.x509verify = 0;
8d5d2d4c 3191#endif
70848515
TS
3192}
3193
14f7143e 3194int vnc_display_password(const char *id, const char *password)
70848515 3195{
14f7143e 3196 VncDisplay *vs = vnc_display_find(id);
70848515 3197
7ef92331 3198 if (!vs) {
a6aa9d3e 3199 return -EINVAL;
7ef92331 3200 }
cf864569
GH
3201 if (vs->auth == VNC_AUTH_NONE) {
3202 error_printf_unless_qmp("If you want use passwords please enable "
3203 "password auth using '-vnc ${dpy},password'.");
3204 return -EINVAL;
1cd20f8b
AL
3205 }
3206
64641d87 3207 g_free(vs->password);
c14e9847 3208 vs->password = g_strdup(password);
a6aa9d3e
LC
3209
3210 return 0;
71cab5ca
TS
3211}
3212
14f7143e 3213int vnc_display_pw_expire(const char *id, time_t expires)
3c9405a0 3214{
14f7143e 3215 VncDisplay *vs = vnc_display_find(id);
3c9405a0 3216
1643f2b2
GH
3217 if (!vs) {
3218 return -EINVAL;
3219 }
3220
3c9405a0
GH
3221 vs->expires = expires;
3222 return 0;
3223}
3224
14f7143e 3225char *vnc_display_local_addr(const char *id)
f92f8afe 3226{
14f7143e 3227 VncDisplay *vs = vnc_display_find(id);
d616ccc5 3228
9e0ff75e 3229 assert(vs);
f92f8afe
AL
3230 return vnc_socket_local_addr("%s:%s", vs->lsock);
3231}
3232
4db14629
GH
3233static QemuOptsList qemu_vnc_opts = {
3234 .name = "vnc",
3235 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3236 .implied_opt_name = "vnc",
3237 .desc = {
3238 {
3239 .name = "vnc",
3240 .type = QEMU_OPT_STRING,
3241 },{
3242 .name = "websocket",
3243 .type = QEMU_OPT_STRING,
3244 },{
3245 .name = "x509",
3246 .type = QEMU_OPT_STRING,
3247 },{
3248 .name = "share",
3249 .type = QEMU_OPT_STRING,
1d0d59fe
GH
3250 },{
3251 .name = "display",
3252 .type = QEMU_OPT_STRING,
3253 },{
3254 .name = "head",
3255 .type = QEMU_OPT_NUMBER,
e5f34cdd
GH
3256 },{
3257 .name = "connections",
3258 .type = QEMU_OPT_NUMBER,
88428b7a
GA
3259 },{
3260 .name = "to",
3261 .type = QEMU_OPT_NUMBER,
3262 },{
3263 .name = "ipv4",
3264 .type = QEMU_OPT_BOOL,
3265 },{
3266 .name = "ipv6",
3267 .type = QEMU_OPT_BOOL,
4db14629
GH
3268 },{
3269 .name = "password",
3270 .type = QEMU_OPT_BOOL,
3271 },{
3272 .name = "reverse",
3273 .type = QEMU_OPT_BOOL,
3274 },{
3275 .name = "lock-key-sync",
3276 .type = QEMU_OPT_BOOL,
3277 },{
3278 .name = "sasl",
3279 .type = QEMU_OPT_BOOL,
3280 },{
3281 .name = "tls",
3282 .type = QEMU_OPT_BOOL,
3283 },{
3284 .name = "x509verify",
8c7d0645 3285 .type = QEMU_OPT_STRING,
4db14629
GH
3286 },{
3287 .name = "acl",
3288 .type = QEMU_OPT_BOOL,
3289 },{
3290 .name = "lossy",
3291 .type = QEMU_OPT_BOOL,
3292 },{
3293 .name = "non-adaptive",
3294 .type = QEMU_OPT_BOOL,
3295 },
3296 { /* end of list */ }
3297 },
3298};
3299
0dd72e15
DB
3300
3301static void
3302vnc_display_setup_auth(VncDisplay *vs,
3303 bool password,
3304 bool sasl,
3305 bool tls,
f9148c8a
DB
3306 bool x509,
3307 bool websocket)
0dd72e15
DB
3308{
3309 /*
3310 * We have a choice of 3 authentication options
3311 *
3312 * 1. none
3313 * 2. vnc
3314 * 3. sasl
3315 *
3316 * The channel can be run in 2 modes
3317 *
3318 * 1. clear
3319 * 2. tls
3320 *
3321 * And TLS can use 2 types of credentials
3322 *
3323 * 1. anon
3324 * 2. x509
3325 *
3326 * We thus have 9 possible logical combinations
3327 *
3328 * 1. clear + none
3329 * 2. clear + vnc
3330 * 3. clear + sasl
3331 * 4. tls + anon + none
3332 * 5. tls + anon + vnc
3333 * 6. tls + anon + sasl
3334 * 7. tls + x509 + none
3335 * 8. tls + x509 + vnc
3336 * 9. tls + x509 + sasl
3337 *
3338 * These need to be mapped into the VNC auth schemes
3339 * in an appropriate manner. In regular VNC, all the
3340 * TLS options get mapped into VNC_AUTH_VENCRYPT
3341 * sub-auth types.
f9148c8a
DB
3342 *
3343 * In websockets, the https:// protocol already provides
3344 * TLS support, so there is no need to make use of the
3345 * VeNCrypt extension. Furthermore, websockets browser
3346 * clients could not use VeNCrypt even if they wanted to,
3347 * as they cannot control when the TLS handshake takes
3348 * place. Thus there is no option but to rely on https://,
3349 * meaning combinations 4->6 and 7->9 will be mapped to
3350 * VNC auth schemes in the same way as combos 1->3.
3351 *
3352 * Regardless of fact that we have a different mapping to
3353 * VNC auth mechs for plain VNC vs websockets VNC, the end
3354 * result has the same security characteristics.
0dd72e15
DB
3355 */
3356 if (password) {
3357 if (tls) {
3358 vs->auth = VNC_AUTH_VENCRYPT;
f9148c8a
DB
3359 if (websocket) {
3360 vs->ws_tls = true;
3361 }
0dd72e15
DB
3362 if (x509) {
3363 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3364 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
3365 } else {
3366 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3367 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3368 }
3369 } else {
3370 VNC_DEBUG("Initializing VNC server with password auth\n");
3371 vs->auth = VNC_AUTH_VNC;
3372 vs->subauth = VNC_AUTH_INVALID;
3373 }
f9148c8a
DB
3374 if (websocket) {
3375 vs->ws_auth = VNC_AUTH_VNC;
3376 } else {
3377 vs->ws_auth = VNC_AUTH_INVALID;
3378 }
0dd72e15
DB
3379 } else if (sasl) {
3380 if (tls) {
3381 vs->auth = VNC_AUTH_VENCRYPT;
f9148c8a
DB
3382 if (websocket) {
3383 vs->ws_tls = true;
3384 }
0dd72e15
DB
3385 if (x509) {
3386 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3387 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
3388 } else {
3389 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3390 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3391 }
3392 } else {
3393 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3394 vs->auth = VNC_AUTH_SASL;
3395 vs->subauth = VNC_AUTH_INVALID;
3396 }
f9148c8a
DB
3397 if (websocket) {
3398 vs->ws_auth = VNC_AUTH_SASL;
3399 } else {
3400 vs->ws_auth = VNC_AUTH_INVALID;
3401 }
0dd72e15
DB
3402 } else {
3403 if (tls) {
3404 vs->auth = VNC_AUTH_VENCRYPT;
f9148c8a
DB
3405 if (websocket) {
3406 vs->ws_tls = true;
3407 }
0dd72e15
DB
3408 if (x509) {
3409 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3410 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
3411 } else {
3412 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3413 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3414 }
3415 } else {
3416 VNC_DEBUG("Initializing VNC server with no auth\n");
3417 vs->auth = VNC_AUTH_NONE;
3418 vs->subauth = VNC_AUTH_INVALID;
3419 }
f9148c8a
DB
3420 if (websocket) {
3421 vs->ws_auth = VNC_AUTH_NONE;
3422 } else {
3423 vs->ws_auth = VNC_AUTH_INVALID;
3424 }
0dd72e15
DB
3425 }
3426}
3427
4db14629 3428void vnc_display_open(const char *id, Error **errp)
71cab5ca 3429{
14f7143e 3430 VncDisplay *vs = vnc_display_find(id);
4db14629 3431 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
e5560329 3432 QemuOpts *sopts, *wsopts;
e2a11d9d 3433 const char *share, *device_id;
1d0d59fe 3434 QemuConsole *con;
a2c72de0
GA
3435 bool password = false;
3436 bool reverse = false;
e2a11d9d
GA
3437 const char *vnc;
3438 const char *has_to;
e5560329 3439 char *h;
e2a11d9d
GA
3440 bool has_ipv4 = false;
3441 bool has_ipv6 = false;
4478aa76 3442 const char *websocket;
a2c72de0 3443 bool tls = false, x509 = false;
d169f04b 3444#ifdef CONFIG_VNC_TLS
4db14629 3445 const char *path;
8d5d2d4c 3446#endif
a2c72de0 3447 bool sasl = false;
d169f04b 3448#ifdef CONFIG_VNC_SASL
2f9606b3
AL
3449 int saslErr;
3450#endif
2ded6ad7 3451#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
76655d6d 3452 int acl = 0;
2ded6ad7 3453#endif
3a0558b5 3454 int lock_key_sync = 1;
71cab5ca 3455
d616ccc5 3456 if (!vs) {
2d55f0e8
PB
3457 error_setg(errp, "VNC display not active");
3458 return;
3459 }
14f7143e 3460 vnc_display_close(vs);
24236869 3461
4db14629
GH
3462 if (!opts) {
3463 return;
3464 }
e2a11d9d
GA
3465 vnc = qemu_opt_get(opts, "vnc");
3466 if (!vnc || strcmp(vnc, "none") == 0) {
4db14629
GH
3467 return;
3468 }
e2a11d9d 3469
e5560329
GH
3470 sopts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
3471 wsopts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
3472
3473 h = strrchr(vnc, ':');
3474 if (h) {
274c3b52
JT
3475 char *host;
3476 size_t hlen = h - vnc;
3477
3478 if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
3479 host = g_strndup(vnc + 1, hlen - 2);
3480 } else {
3481 host = g_strndup(vnc, hlen);
3482 }
e5560329
GH
3483 qemu_opt_set(sopts, "host", host, &error_abort);
3484 qemu_opt_set(wsopts, "host", host, &error_abort);
3485 qemu_opt_set(sopts, "port", h+1, &error_abort);
3486 g_free(host);
3487 } else {
3488 error_setg(errp, "no vnc port specified");
3489 goto fail;
e2a11d9d 3490 }
e5560329
GH
3491
3492 has_to = qemu_opt_get(opts, "to");
e2a11d9d
GA
3493 has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3494 has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
e5560329
GH
3495 if (has_to) {
3496 qemu_opt_set(sopts, "to", has_to, &error_abort);
3497 qemu_opt_set(wsopts, "to", has_to, &error_abort);
3498 }
3499 if (has_ipv4) {
3500 qemu_opt_set(sopts, "ipv4", "on", &error_abort);
3501 qemu_opt_set(wsopts, "ipv4", "on", &error_abort);
3502 }
3503 if (has_ipv6) {
3504 qemu_opt_set(sopts, "ipv6", "on", &error_abort);
3505 qemu_opt_set(wsopts, "ipv6", "on", &error_abort);
3506 }
4db14629
GH
3507
3508 password = qemu_opt_get_bool(opts, "password", false);
800567a6
DB
3509 if (password) {
3510 if (fips_get_state()) {
3511 error_setg(errp,
3512 "VNC password auth disabled due to FIPS mode, "
3513 "consider using the VeNCrypt or SASL authentication "
3514 "methods as an alternative");
3515 goto fail;
3516 }
3517 if (!qcrypto_cipher_supports(
3518 QCRYPTO_CIPHER_ALG_DES_RFB)) {
3519 error_setg(errp,
3520 "Cipher backend does not support DES RFB algorithm");
3521 goto fail;
3522 }
4db14629
GH
3523 }
3524
3525 reverse = qemu_opt_get_bool(opts, "reverse", false);
3526 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
4db14629 3527 sasl = qemu_opt_get_bool(opts, "sasl", false);
d169f04b
DB
3528#ifndef CONFIG_VNC_SASL
3529 if (sasl) {
3530 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3531 goto fail;
3532 }
3533#endif /* CONFIG_VNC_SASL */
4db14629 3534 tls = qemu_opt_get_bool(opts, "tls", false);
d169f04b 3535#ifdef CONFIG_VNC_TLS
4db14629 3536 path = qemu_opt_get(opts, "x509");
8c7d0645
DB
3537 if (!path) {
3538 path = qemu_opt_get(opts, "x509verify");
3539 if (path) {
3540 vs->tls.x509verify = true;
3541 }
3542 }
4db14629 3543 if (path) {
a2c72de0 3544 x509 = true;
4db14629
GH
3545 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
3546 error_setg(errp, "Failed to find x509 certificates/keys in %s",
3547 path);
3548 goto fail;
3549 }
3550 }
d169f04b
DB
3551#else /* ! CONFIG_VNC_TLS */
3552 if (tls) {
3553 error_setg(errp, "VNC TLS auth requires gnutls support");
3554 goto fail;
3555 }
3556#endif /* ! CONFIG_VNC_TLS */
2ded6ad7 3557#if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
4db14629 3558 acl = qemu_opt_get_bool(opts, "acl", false);
e22492d3 3559#endif
4db14629
GH
3560
3561 share = qemu_opt_get(opts, "share");
3562 if (share) {
3563 if (strcmp(share, "ignore") == 0) {
3564 vs->share_policy = VNC_SHARE_POLICY_IGNORE;
3565 } else if (strcmp(share, "allow-exclusive") == 0) {
3566 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3567 } else if (strcmp(share, "force-shared") == 0) {
3568 vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
3569 } else {
3570 error_setg(errp, "unknown vnc share= option");
3571 goto fail;
3572 }
3573 } else {
3574 vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3575 }
e5f34cdd 3576 vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4db14629 3577
4db14629
GH
3578 websocket = qemu_opt_get(opts, "websocket");
3579 if (websocket) {
bf7aa45e 3580 vs->ws_enabled = true;
e5560329 3581 qemu_opt_set(wsopts, "port", websocket, &error_abort);
8e9b0d24
DB
3582 if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3583 error_setg(errp, "SHA1 hash support is required for websockets");
3584 goto fail;
3585 }
70848515
TS
3586 }
3587
4db14629
GH
3588#ifdef CONFIG_VNC_JPEG
3589 vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
3590#endif
3591 vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
e22492d3
PL
3592 /* adaptive updates are only used with tight encoding and
3593 * if lossy updates are enabled so we can disable all the
3594 * calculations otherwise */
3595 if (!vs->lossy) {
3596 vs->non_adaptive = true;
3597 }
3598
76655d6d
AL
3599#ifdef CONFIG_VNC_TLS
3600 if (acl && x509 && vs->tls.x509verify) {
c8496408
GH
3601 char *aclname;
3602
3603 if (strcmp(vs->id, "default") == 0) {
3604 aclname = g_strdup("vnc.x509dname");
3605 } else {
3606 aclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
3607 }
3608 vs->tls.acl = qemu_acl_init(aclname);
c8496408 3609 g_free(aclname);
76655d6d
AL
3610 }
3611#endif
3612#ifdef CONFIG_VNC_SASL
3613 if (acl && sasl) {
c8496408
GH
3614 char *aclname;
3615
3616 if (strcmp(vs->id, "default") == 0) {
3617 aclname = g_strdup("vnc.username");
3618 } else {
3619 aclname = g_strdup_printf("vnc.%s.username", vs->id);
3620 }
3621 vs->sasl.acl = qemu_acl_init(aclname);
c8496408 3622 g_free(aclname);
76655d6d
AL
3623 }
3624#endif
3625
f9148c8a 3626 vnc_display_setup_auth(vs, password, sasl, tls, x509, websocket);
24236869 3627
2f9606b3
AL
3628#ifdef CONFIG_VNC_SASL
3629 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2d55f0e8
PB
3630 error_setg(errp, "Failed to initialize SASL auth: %s",
3631 sasl_errstring(saslErr, NULL, NULL));
1ce52c78 3632 goto fail;
2f9606b3
AL
3633 }
3634#endif
3a0558b5 3635 vs->lock_key_sync = lock_key_sync;
2f9606b3 3636
1d0d59fe
GH
3637 device_id = qemu_opt_get(opts, "display");
3638 if (device_id) {
3639 DeviceState *dev;
3640 int head = qemu_opt_get_number(opts, "head", 0);
3641
3642 dev = qdev_find_recursive(sysbus_get_default(), device_id);
3643 if (dev == NULL) {
f3cf80e8 3644 error_setg(errp, "Device '%s' not found", device_id);
1d0d59fe
GH
3645 goto fail;
3646 }
3647
3648 con = qemu_console_lookup_by_device(dev, head);
3649 if (con == NULL) {
3650 error_setg(errp, "Device %s is not bound to a QemuConsole",
3651 device_id);
3652 goto fail;
3653 }
3654 } else {
3655 con = NULL;
3656 }
3657
3658 if (con != vs->dcl.con) {
3659 unregister_displaychangelistener(&vs->dcl);
3660 vs->dcl.con = con;
3661 register_displaychangelistener(&vs->dcl);
3662 }
3663
3aa3eea3 3664 if (reverse) {
9712ecaf 3665 /* connect to viewer */
007fcd3e
PB
3666 int csock;
3667 vs->lsock = -1;
7536ee4b 3668 vs->lwebsock = -1;
e5560329
GH
3669 if (strncmp(vnc, "unix:", 5) == 0) {
3670 csock = unix_connect(vnc+5, errp);
3aa3eea3 3671 } else {
e5560329 3672 csock = inet_connect(vnc, errp);
3aa3eea3 3673 }
007fcd3e
PB
3674 if (csock < 0) {
3675 goto fail;
3676 }
2c8cf549 3677 vnc_connect(vs, csock, false, false);
9712ecaf
AL
3678 } else {
3679 /* listen for connects */
e5560329
GH
3680 if (strncmp(vnc, "unix:", 5) == 0) {
3681 vs->lsock = unix_listen(vnc+5, NULL, 0, errp);
3d00ac1a
CR
3682 if (vs->lsock < 0) {
3683 goto fail;
3684 }
bf7aa45e 3685 vs->is_unix = true;
9712ecaf 3686 } else {
e5560329 3687 vs->lsock = inet_listen_opts(sopts, 5900, errp);
7536ee4b 3688 if (vs->lsock < 0) {
7536ee4b
TH
3689 goto fail;
3690 }
bf7aa45e 3691 if (vs->ws_enabled) {
e5560329 3692 vs->lwebsock = inet_listen_opts(wsopts, 0, errp);
7536ee4b 3693 if (vs->lwebsock < 0) {
b3c33f91 3694 if (vs->lsock != -1) {
7536ee4b
TH
3695 close(vs->lsock);
3696 vs->lsock = -1;
3697 }
7536ee4b
TH
3698 goto fail;
3699 }
3700 }
9712ecaf 3701 }
bf7aa45e 3702 vs->enabled = true;
82e1cc4b 3703 qemu_set_fd_handler(vs->lsock, vnc_listen_regular_read, NULL, vs);
bf7aa45e 3704 if (vs->ws_enabled) {
82e1cc4b
FZ
3705 qemu_set_fd_handler(vs->lwebsock, vnc_listen_websocket_read,
3706 NULL, vs);
7536ee4b 3707 }
24236869 3708 }
e5560329
GH
3709 qemu_opts_del(sopts);
3710 qemu_opts_del(wsopts);
2d55f0e8 3711 return;
1ce52c78
PB
3712
3713fail:
e5560329
GH
3714 qemu_opts_del(sopts);
3715 qemu_opts_del(wsopts);
bf7aa45e 3716 vs->enabled = false;
bf7aa45e 3717 vs->ws_enabled = false;
24236869 3718}
13661089 3719
14f7143e 3720void vnc_display_add_client(const char *id, int csock, bool skipauth)
13661089 3721{
14f7143e 3722 VncDisplay *vs = vnc_display_find(id);
13661089 3723
d616ccc5
GH
3724 if (!vs) {
3725 return;
3726 }
2c8cf549 3727 vnc_connect(vs, csock, skipauth, false);
13661089 3728}
4db14629 3729
9634f4e3 3730static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
2779672f
GA
3731{
3732 int i = 2;
3733 char *id;
3734
3735 id = g_strdup("default");
3736 while (qemu_opts_find(olist, id)) {
3737 g_free(id);
3738 id = g_strdup_printf("vnc%d", i++);
3739 }
3740 qemu_opts_set_id(opts, id);
3741}
3742
70b94331 3743QemuOpts *vnc_parse(const char *str, Error **errp)
4db14629 3744{
4db14629 3745 QemuOptsList *olist = qemu_find_opts("vnc");
70b94331 3746 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
81607cbf 3747 const char *id;
4db14629 3748
81607cbf
GA
3749 if (!opts) {
3750 return NULL;
3751 }
3752
3753 id = qemu_opts_id(opts);
4db14629
GH
3754 if (!id) {
3755 /* auto-assign id if not present */
2779672f 3756 vnc_auto_assign_id(olist, opts);
4db14629 3757 }
9634f4e3
GH
3758 return opts;
3759}
3760
28d0de7a 3761int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
9634f4e3
GH
3762{
3763 Error *local_err = NULL;
3764 char *id = (char *)qemu_opts_id(opts);
4db14629 3765
9634f4e3 3766 assert(id);
4db14629
GH
3767 vnc_display_init(id);
3768 vnc_display_open(id, &local_err);
3769 if (local_err != NULL) {
bc119048 3770 error_report("Failed to start VNC server: %s",
4db14629
GH
3771 error_get_pretty(local_err));
3772 error_free(local_err);
3773 exit(1);
3774 }
3775 return 0;
3776}
3777
3778static void vnc_register_config(void)
3779{
3780 qemu_add_opts(&qemu_vnc_opts);
3781}
3782machine_init(vnc_register_config);