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