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