]> Git Repo - qemu.git/blame - ui/vnc.c
Merge remote-tracking branch 'remotes/xtensa/tags/20180122-xtensa' into staging
[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
30b80fd5 1275size_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
30b80fd5 1318 * 0 on I/O error, and disconnects the client socket.
2f9606b3 1319 */
30b80fd5 1320size_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
30b80fd5
DB
1338 * the buffered output data if the socket would block. Returns
1339 * 0 on I/O error, and disconnects the client socket.
2f9606b3 1340 */
30b80fd5 1341static size_t vnc_client_write_plain(VncState *vs)
2f9606b3 1342{
6aa22a29 1343 size_t offset;
30b80fd5 1344 size_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
30b80fd5 1445 * 0 on I/O error or EOF, and disconnects the client socket.
2f9606b3 1446 */
30b80fd5 1447size_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 *
30b80fd5
DB
1463 * Returns the number of bytes read, which may be less than
1464 * the requested 'datalen' if the socket would block. Returns
1465 * 0 on I/O error or EOF, and disconnects the client socket.
2f9606b3 1466 */
30b80fd5 1467static size_t vnc_client_read_plain(VncState *vs)
2f9606b3 1468{
30b80fd5 1469 size_t ret;
23decc87 1470 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
2f9606b3
AL
1471 vs->input.buffer, vs->input.capacity, vs->input.offset);
1472 buffer_reserve(&vs->input, 4096);
1473 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1474 if (!ret)
1475 return 0;
24236869 1476 vs->input.offset += ret;
2f9606b3
AL
1477 return ret;
1478}
1479
175b2a6e
CC
1480static void vnc_jobs_bh(void *opaque)
1481{
1482 VncState *vs = opaque;
1483
1484 vnc_jobs_consume_buffer(vs);
1485}
2f9606b3
AL
1486
1487/*
1488 * First function called whenever there is more data to be read from
1489 * the client socket. Will delegate actual work according to whether
1490 * SASL SSF layers are enabled (thus requiring decryption calls)
ea697449 1491 * Returns 0 on success, -1 if client disconnected
2f9606b3 1492 */
ea697449 1493static int vnc_client_read(VncState *vs)
2f9606b3 1494{
30b80fd5 1495 size_t ret;
2f9606b3
AL
1496
1497#ifdef CONFIG_VNC_SASL
1498 if (vs->sasl.conn && vs->sasl.runSSF)
1499 ret = vnc_client_read_sasl(vs);
1500 else
1501#endif /* CONFIG_VNC_SASL */
d5f04223 1502 ret = vnc_client_read_plain(vs);
198a0039 1503 if (!ret) {
04d2529d 1504 if (vs->disconnecting) {
198a0039 1505 vnc_disconnect_finish(vs);
ea697449 1506 return -1;
04d2529d 1507 }
ea697449 1508 return 0;
198a0039 1509 }
24236869
FB
1510
1511 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
28a76be8
AL
1512 size_t len = vs->read_handler_expect;
1513 int ret;
1514
1515 ret = vs->read_handler(vs, vs->input.buffer, len);
04d2529d 1516 if (vs->disconnecting) {
198a0039 1517 vnc_disconnect_finish(vs);
ea697449 1518 return -1;
198a0039 1519 }
28a76be8
AL
1520
1521 if (!ret) {
32ed2680 1522 buffer_advance(&vs->input, len);
28a76be8
AL
1523 } else {
1524 vs->read_handler_expect = ret;
1525 }
24236869 1526 }
ea697449 1527 return 0;
24236869
FB
1528}
1529
04d2529d
DB
1530gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1531 GIOCondition condition, void *opaque)
1532{
1533 VncState *vs = opaque;
1534 if (condition & G_IO_IN) {
ea697449
DB
1535 if (vnc_client_read(vs) < 0) {
1536 return TRUE;
1537 }
04d2529d
DB
1538 }
1539 if (condition & G_IO_OUT) {
1540 vnc_client_write(vs);
1541 }
1542 return TRUE;
1543}
1544
1545
f887cf16
DB
1546/*
1547 * Scale factor to apply to vs->throttle_output_offset when checking for
1548 * hard limit. Worst case normal usage could be x2, if we have a complete
1549 * incremental update and complete forced update in the output buffer.
1550 * So x3 should be good enough, but we pick x5 to be conservative and thus
1551 * (hopefully) never trigger incorrectly.
1552 */
1553#define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
1554
5fb6c7a8 1555void vnc_write(VncState *vs, const void *data, size_t len)
24236869 1556{
f887cf16
DB
1557 if (vs->disconnecting) {
1558 return;
1559 }
1560 /* Protection against malicious client/guest to prevent our output
1561 * buffer growing without bound if client stops reading data. This
1562 * should rarely trigger, because we have earlier throttling code
1563 * which stops issuing framebuffer updates and drops audio data
1564 * if the throttle_output_offset value is exceeded. So we only reach
1565 * this higher level if a huge number of pseudo-encodings get
1566 * triggered while data can't be sent on the socket.
1567 *
1568 * NB throttle_output_offset can be zero during early protocol
1569 * handshake, or from the job thread's VncState clone
1570 */
1571 if (vs->throttle_output_offset != 0 &&
1572 vs->output.offset > (vs->throttle_output_offset *
1573 VNC_THROTTLE_OUTPUT_LIMIT_SCALE)) {
6aa22a29
DB
1574 trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
1575 vs->throttle_output_offset);
f887cf16
DB
1576 vnc_disconnect_start(vs);
1577 return;
1578 }
24236869
FB
1579 buffer_reserve(&vs->output, len);
1580
04d2529d
DB
1581 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1582 if (vs->ioc_tag) {
1583 g_source_remove(vs->ioc_tag);
1584 }
1585 vs->ioc_tag = qio_channel_add_watch(
1586 vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
24236869
FB
1587 }
1588
1589 buffer_append(&vs->output, data, len);
1590}
1591
5fb6c7a8 1592void vnc_write_s32(VncState *vs, int32_t value)
24236869
FB
1593{
1594 vnc_write_u32(vs, *(uint32_t *)&value);
1595}
1596
5fb6c7a8 1597void vnc_write_u32(VncState *vs, uint32_t value)
24236869
FB
1598{
1599 uint8_t buf[4];
1600
1601 buf[0] = (value >> 24) & 0xFF;
1602 buf[1] = (value >> 16) & 0xFF;
1603 buf[2] = (value >> 8) & 0xFF;
1604 buf[3] = value & 0xFF;
1605
1606 vnc_write(vs, buf, 4);
1607}
1608
5fb6c7a8 1609void vnc_write_u16(VncState *vs, uint16_t value)
24236869 1610{
64f5a135 1611 uint8_t buf[2];
24236869
FB
1612
1613 buf[0] = (value >> 8) & 0xFF;
1614 buf[1] = value & 0xFF;
1615
1616 vnc_write(vs, buf, 2);
1617}
1618
5fb6c7a8 1619void vnc_write_u8(VncState *vs, uint8_t value)
24236869
FB
1620{
1621 vnc_write(vs, (char *)&value, 1);
1622}
1623
5fb6c7a8 1624void vnc_flush(VncState *vs)
24236869 1625{
bd023f95 1626 vnc_lock_output(vs);
d5f04223 1627 if (vs->ioc != NULL && vs->output.offset) {
bd023f95
CC
1628 vnc_client_write_locked(vs);
1629 }
1630 vnc_unlock_output(vs);
24236869
FB
1631}
1632
71a8cdec 1633static uint8_t read_u8(uint8_t *data, size_t offset)
24236869
FB
1634{
1635 return data[offset];
1636}
1637
71a8cdec 1638static uint16_t read_u16(uint8_t *data, size_t offset)
24236869
FB
1639{
1640 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1641}
1642
71a8cdec 1643static int32_t read_s32(uint8_t *data, size_t offset)
24236869
FB
1644{
1645 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1646 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1647}
1648
5fb6c7a8 1649uint32_t read_u32(uint8_t *data, size_t offset)
24236869
FB
1650{
1651 return ((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1652 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1653}
1654
60fe76f3 1655static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
24236869
FB
1656{
1657}
1658
9e8dd451 1659static void check_pointer_type_change(Notifier *notifier, void *data)
564c337e 1660{
37c34d9d 1661 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
14768eba 1662 int absolute = qemu_input_is_absolute();
37c34d9d 1663
29fa4ed9 1664 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
bd023f95 1665 vnc_lock_output(vs);
46a183da 1666 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
28a76be8
AL
1667 vnc_write_u8(vs, 0);
1668 vnc_write_u16(vs, 1);
1669 vnc_framebuffer_update(vs, absolute, 0,
bea60dd7
PL
1670 pixman_image_get_width(vs->vd->server),
1671 pixman_image_get_height(vs->vd->server),
29fa4ed9 1672 VNC_ENCODING_POINTER_TYPE_CHANGE);
bd023f95 1673 vnc_unlock_output(vs);
28a76be8 1674 vnc_flush(vs);
564c337e
FB
1675 }
1676 vs->absolute = absolute;
1677}
1678
24236869
FB
1679static void pointer_event(VncState *vs, int button_mask, int x, int y)
1680{
7fb1cf16 1681 static uint32_t bmap[INPUT_BUTTON__MAX] = {
14768eba
GH
1682 [INPUT_BUTTON_LEFT] = 0x01,
1683 [INPUT_BUTTON_MIDDLE] = 0x02,
1684 [INPUT_BUTTON_RIGHT] = 0x04,
f22d0af0
GH
1685 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1686 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
14768eba
GH
1687 };
1688 QemuConsole *con = vs->vd->dcl.con;
bea60dd7
PL
1689 int width = pixman_image_get_width(vs->vd->server);
1690 int height = pixman_image_get_height(vs->vd->server);
24236869 1691
14768eba
GH
1692 if (vs->last_bmask != button_mask) {
1693 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1694 vs->last_bmask = button_mask;
1695 }
564c337e
FB
1696
1697 if (vs->absolute) {
9cfa7ab9
PV
1698 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1699 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
29fa4ed9 1700 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
14768eba
GH
1701 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1702 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
564c337e 1703 } else {
14768eba
GH
1704 if (vs->last_x != -1) {
1705 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1706 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1707 }
28a76be8
AL
1708 vs->last_x = x;
1709 vs->last_y = y;
24236869 1710 }
14768eba 1711 qemu_input_event_sync();
24236869
FB
1712}
1713
64f5a135
FB
1714static void reset_keys(VncState *vs)
1715{
1716 int i;
1717 for(i = 0; i < 256; i++) {
1718 if (vs->modifiers_state[i]) {
8d447d10 1719 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
c5ce8333 1720 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
64f5a135
FB
1721 vs->modifiers_state[i] = 0;
1722 }
1723 }
1724}
1725
a528b80c
AZ
1726static void press_key(VncState *vs, int keysym)
1727{
44bb61c8 1728 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
8d447d10 1729 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
c5ce8333 1730 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
8d447d10 1731 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
c5ce8333 1732 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
a528b80c
AZ
1733}
1734
ab99e5c1
LL
1735static void vnc_led_state_change(VncState *vs)
1736{
ab99e5c1
LL
1737 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1738 return;
1739 }
1740
ab99e5c1
LL
1741 vnc_lock_output(vs);
1742 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1743 vnc_write_u8(vs, 0);
1744 vnc_write_u16(vs, 1);
1745 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
a54f0d2b 1746 vnc_write_u8(vs, vs->vd->ledstate);
ab99e5c1
LL
1747 vnc_unlock_output(vs);
1748 vnc_flush(vs);
1749}
1750
7ffb82ca
GH
1751static void kbd_leds(void *opaque, int ledstate)
1752{
a54f0d2b
PO
1753 VncDisplay *vd = opaque;
1754 VncState *client;
7ffb82ca 1755
40066175
GH
1756 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1757 (ledstate & QEMU_NUM_LOCK_LED),
1758 (ledstate & QEMU_SCROLL_LOCK_LED));
1759
a54f0d2b
PO
1760 if (ledstate == vd->ledstate) {
1761 return;
96f3d174 1762 }
ab99e5c1 1763
a54f0d2b
PO
1764 vd->ledstate = ledstate;
1765
1766 QTAILQ_FOREACH(client, &vd->clients, next) {
1767 vnc_led_state_change(client);
ab99e5c1 1768 }
7ffb82ca
GH
1769}
1770
9ca313aa 1771static void do_key_event(VncState *vs, int down, int keycode, int sym)
24236869 1772{
64f5a135
FB
1773 /* QEMU console switch */
1774 switch(keycode) {
1775 case 0x2a: /* Left Shift */
1776 case 0x36: /* Right Shift */
1777 case 0x1d: /* Left CTRL */
1778 case 0x9d: /* Right CTRL */
1779 case 0x38: /* Left ALT */
1780 case 0xb8: /* Right ALT */
1781 if (down)
1782 vs->modifiers_state[keycode] = 1;
1783 else
1784 vs->modifiers_state[keycode] = 0;
1785 break;
5fafdf24 1786 case 0x02 ... 0x0a: /* '1' to '9' keys */
1d0d59fe
GH
1787 if (vs->vd->dcl.con == NULL &&
1788 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
64f5a135
FB
1789 /* Reset the modifiers sent to the current console */
1790 reset_keys(vs);
1791 console_select(keycode - 0x02);
1792 return;
1793 }
1794 break;
28a76be8
AL
1795 case 0x3a: /* CapsLock */
1796 case 0x45: /* NumLock */
7ffb82ca 1797 if (down)
a528b80c
AZ
1798 vs->modifiers_state[keycode] ^= 1;
1799 break;
1800 }
1801
e7b2aacc
LL
1802 /* Turn off the lock state sync logic if the client support the led
1803 state extension.
1804 */
9892088b 1805 if (down && vs->vd->lock_key_sync &&
e7b2aacc 1806 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
3a0558b5 1807 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
a528b80c
AZ
1808 /* If the numlock state needs to change then simulate an additional
1809 keypress before sending this one. This will happen if the user
1810 toggles numlock away from the VNC window.
1811 */
753b4053 1812 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
a528b80c 1813 if (!vs->modifiers_state[0x45]) {
40066175 1814 trace_vnc_key_sync_numlock(true);
a528b80c
AZ
1815 vs->modifiers_state[0x45] = 1;
1816 press_key(vs, 0xff7f);
1817 }
1818 } else {
1819 if (vs->modifiers_state[0x45]) {
40066175 1820 trace_vnc_key_sync_numlock(false);
a528b80c
AZ
1821 vs->modifiers_state[0x45] = 0;
1822 press_key(vs, 0xff7f);
1823 }
1824 }
64f5a135 1825 }
24236869 1826
9892088b 1827 if (down && vs->vd->lock_key_sync &&
e7b2aacc 1828 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
3a0558b5 1829 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
6b132502
GH
1830 /* If the capslock state needs to change then simulate an additional
1831 keypress before sending this one. This will happen if the user
1832 toggles capslock away from the VNC window.
1833 */
1834 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1835 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1836 int capslock = !!(vs->modifiers_state[0x3a]);
1837 if (capslock) {
1838 if (uppercase == shift) {
40066175 1839 trace_vnc_key_sync_capslock(false);
6b132502
GH
1840 vs->modifiers_state[0x3a] = 0;
1841 press_key(vs, 0xffe5);
1842 }
1843 } else {
1844 if (uppercase != shift) {
40066175 1845 trace_vnc_key_sync_capslock(true);
6b132502
GH
1846 vs->modifiers_state[0x3a] = 1;
1847 press_key(vs, 0xffe5);
1848 }
1849 }
1850 }
1851
81c0d5a6 1852 if (qemu_console_is_graphic(NULL)) {
8d447d10 1853 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
c5ce8333 1854 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
64f5a135 1855 } else {
e26437c2
GH
1856 bool numlock = vs->modifiers_state[0x45];
1857 bool control = (vs->modifiers_state[0x1d] ||
1858 vs->modifiers_state[0x9d]);
64f5a135
FB
1859 /* QEMU console emulation */
1860 if (down) {
1861 switch (keycode) {
1862 case 0x2a: /* Left Shift */
1863 case 0x36: /* Right Shift */
1864 case 0x1d: /* Left CTRL */
1865 case 0x9d: /* Right CTRL */
1866 case 0x38: /* Left ALT */
1867 case 0xb8: /* Right ALT */
1868 break;
1869 case 0xc8:
1870 kbd_put_keysym(QEMU_KEY_UP);
1871 break;
1872 case 0xd0:
1873 kbd_put_keysym(QEMU_KEY_DOWN);
1874 break;
1875 case 0xcb:
1876 kbd_put_keysym(QEMU_KEY_LEFT);
1877 break;
1878 case 0xcd:
1879 kbd_put_keysym(QEMU_KEY_RIGHT);
1880 break;
1881 case 0xd3:
1882 kbd_put_keysym(QEMU_KEY_DELETE);
1883 break;
1884 case 0xc7:
1885 kbd_put_keysym(QEMU_KEY_HOME);
1886 break;
1887 case 0xcf:
1888 kbd_put_keysym(QEMU_KEY_END);
1889 break;
1890 case 0xc9:
1891 kbd_put_keysym(QEMU_KEY_PAGEUP);
1892 break;
1893 case 0xd1:
1894 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1895 break;
bb0a18e1
GH
1896
1897 case 0x47:
1898 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1899 break;
1900 case 0x48:
1901 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1902 break;
1903 case 0x49:
1904 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1905 break;
1906 case 0x4b:
1907 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1908 break;
1909 case 0x4c:
1910 kbd_put_keysym('5');
1911 break;
1912 case 0x4d:
1913 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1914 break;
1915 case 0x4f:
1916 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1917 break;
1918 case 0x50:
1919 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1920 break;
1921 case 0x51:
1922 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1923 break;
1924 case 0x52:
1925 kbd_put_keysym('0');
1926 break;
1927 case 0x53:
1928 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1929 break;
1930
1931 case 0xb5:
1932 kbd_put_keysym('/');
1933 break;
1934 case 0x37:
1935 kbd_put_keysym('*');
1936 break;
1937 case 0x4a:
1938 kbd_put_keysym('-');
1939 break;
1940 case 0x4e:
1941 kbd_put_keysym('+');
1942 break;
1943 case 0x9c:
1944 kbd_put_keysym('\n');
1945 break;
1946
64f5a135 1947 default:
e26437c2
GH
1948 if (control) {
1949 kbd_put_keysym(sym & 0x1f);
1950 } else {
1951 kbd_put_keysym(sym);
1952 }
64f5a135
FB
1953 break;
1954 }
1955 }
1956 }
24236869
FB
1957}
1958
7bc9318b
GH
1959static void vnc_release_modifiers(VncState *vs)
1960{
1961 static const int keycodes[] = {
1962 /* shift, control, alt keys, both left & right */
1963 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1964 };
1965 int i, keycode;
1966
81c0d5a6 1967 if (!qemu_console_is_graphic(NULL)) {
7bc9318b
GH
1968 return;
1969 }
1970 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1971 keycode = keycodes[i];
1972 if (!vs->modifiers_state[keycode]) {
1973 continue;
1974 }
8d447d10 1975 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
c5ce8333 1976 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
7bc9318b
GH
1977 }
1978}
1979
40066175
GH
1980static const char *code2name(int keycode)
1981{
977c736f 1982 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
40066175
GH
1983}
1984
bdbd7676
FB
1985static void key_event(VncState *vs, int down, uint32_t sym)
1986{
9ca313aa 1987 int keycode;
4a93fe17 1988 int lsym = sym;
9ca313aa 1989
81c0d5a6 1990 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
4a93fe17
GH
1991 lsym = lsym - 'A' + 'a';
1992 }
9ca313aa 1993
44bb61c8 1994 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
40066175 1995 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
9ca313aa
AL
1996 do_key_event(vs, down, keycode, sym);
1997}
1998
1999static void ext_key_event(VncState *vs, int down,
2000 uint32_t sym, uint16_t keycode)
2001{
2002 /* if the user specifies a keyboard layout, always use it */
40066175 2003 if (keyboard_layout) {
9ca313aa 2004 key_event(vs, down, sym);
40066175
GH
2005 } else {
2006 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
9ca313aa 2007 do_key_event(vs, down, keycode, sym);
40066175 2008 }
bdbd7676
FB
2009}
2010
24236869 2011static void framebuffer_update_request(VncState *vs, int incremental,
bea60dd7 2012 int x, int y, int w, int h)
24236869 2013{
bea60dd7 2014 if (incremental) {
fef1bbad
DB
2015 if (vs->update != VNC_STATE_UPDATE_FORCE) {
2016 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
2017 }
2018 } else {
2019 vs->update = VNC_STATE_UPDATE_FORCE;
2020 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
24236869
FB
2021 }
2022}
2023
9ca313aa
AL
2024static void send_ext_key_event_ack(VncState *vs)
2025{
bd023f95 2026 vnc_lock_output(vs);
46a183da 2027 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
9ca313aa
AL
2028 vnc_write_u8(vs, 0);
2029 vnc_write_u16(vs, 1);
d39fa6d8 2030 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2031 pixman_image_get_width(vs->vd->server),
2032 pixman_image_get_height(vs->vd->server),
29fa4ed9 2033 VNC_ENCODING_EXT_KEY_EVENT);
bd023f95 2034 vnc_unlock_output(vs);
9ca313aa
AL
2035 vnc_flush(vs);
2036}
2037
429a8ed3 2038static void send_ext_audio_ack(VncState *vs)
2039{
bd023f95 2040 vnc_lock_output(vs);
46a183da 2041 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
429a8ed3 2042 vnc_write_u8(vs, 0);
2043 vnc_write_u16(vs, 1);
d39fa6d8 2044 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2045 pixman_image_get_width(vs->vd->server),
2046 pixman_image_get_height(vs->vd->server),
29fa4ed9 2047 VNC_ENCODING_AUDIO);
bd023f95 2048 vnc_unlock_output(vs);
429a8ed3 2049 vnc_flush(vs);
2050}
2051
24236869
FB
2052static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2053{
2054 int i;
29fa4ed9 2055 unsigned int enc = 0;
24236869 2056
29fa4ed9 2057 vs->features = 0;
a9f20d31 2058 vs->vnc_encoding = 0;
d1af0e05
CC
2059 vs->tight.compression = 9;
2060 vs->tight.quality = -1; /* Lossless by default */
564c337e 2061 vs->absolute = -1;
24236869 2062
8a0f0d0c
CC
2063 /*
2064 * Start from the end because the encodings are sent in order of preference.
e5bed759 2065 * This way the preferred encoding (first encoding defined in the array)
8a0f0d0c
CC
2066 * will be set at the end of the loop.
2067 */
24236869 2068 for (i = n_encodings - 1; i >= 0; i--) {
29fa4ed9
AL
2069 enc = encodings[i];
2070 switch (enc) {
2071 case VNC_ENCODING_RAW:
a9f20d31 2072 vs->vnc_encoding = enc;
29fa4ed9
AL
2073 break;
2074 case VNC_ENCODING_COPYRECT:
753b4053 2075 vs->features |= VNC_FEATURE_COPYRECT_MASK;
29fa4ed9
AL
2076 break;
2077 case VNC_ENCODING_HEXTILE:
2078 vs->features |= VNC_FEATURE_HEXTILE_MASK;
a9f20d31 2079 vs->vnc_encoding = enc;
29fa4ed9 2080 break;
380282b0
CC
2081 case VNC_ENCODING_TIGHT:
2082 vs->features |= VNC_FEATURE_TIGHT_MASK;
2083 vs->vnc_encoding = enc;
2084 break;
fe3e7f2d 2085#ifdef CONFIG_VNC_PNG
efe556ad
CC
2086 case VNC_ENCODING_TIGHT_PNG:
2087 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2088 vs->vnc_encoding = enc;
2089 break;
fe3e7f2d 2090#endif
059cef40
AL
2091 case VNC_ENCODING_ZLIB:
2092 vs->features |= VNC_FEATURE_ZLIB_MASK;
a9f20d31 2093 vs->vnc_encoding = enc;
059cef40 2094 break;
148954fa
CC
2095 case VNC_ENCODING_ZRLE:
2096 vs->features |= VNC_FEATURE_ZRLE_MASK;
2097 vs->vnc_encoding = enc;
2098 break;
2099 case VNC_ENCODING_ZYWRLE:
2100 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2101 vs->vnc_encoding = enc;
2102 break;
29fa4ed9
AL
2103 case VNC_ENCODING_DESKTOPRESIZE:
2104 vs->features |= VNC_FEATURE_RESIZE_MASK;
2105 break;
2106 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2107 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2108 break;
d467b679
GH
2109 case VNC_ENCODING_RICH_CURSOR:
2110 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
91ec41dc
FZ
2111 if (vs->vd->cursor) {
2112 vnc_cursor_define(vs);
2113 }
d467b679 2114 break;
29fa4ed9 2115 case VNC_ENCODING_EXT_KEY_EVENT:
9ca313aa
AL
2116 send_ext_key_event_ack(vs);
2117 break;
29fa4ed9 2118 case VNC_ENCODING_AUDIO:
429a8ed3 2119 send_ext_audio_ack(vs);
2120 break;
29fa4ed9
AL
2121 case VNC_ENCODING_WMVi:
2122 vs->features |= VNC_FEATURE_WMVI_MASK;
ca4cca4d 2123 break;
ab99e5c1
LL
2124 case VNC_ENCODING_LED_STATE:
2125 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2126 break;
fb437313 2127 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
d1af0e05 2128 vs->tight.compression = (enc & 0x0F);
fb437313
AL
2129 break;
2130 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
b31f519e
CC
2131 if (vs->vd->lossy) {
2132 vs->tight.quality = (enc & 0x0F);
2133 }
fb437313 2134 break;
29fa4ed9
AL
2135 default:
2136 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2137 break;
2138 }
24236869 2139 }
6356e472 2140 vnc_desktop_resize(vs);
9e8dd451 2141 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
ab99e5c1 2142 vnc_led_state_change(vs);
24236869
FB
2143}
2144
6cec5487
AL
2145static void set_pixel_conversion(VncState *vs)
2146{
9f64916d
GH
2147 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2148
2149 if (fmt == VNC_SERVER_FB_FORMAT) {
6cec5487 2150 vs->write_pixels = vnc_write_pixels_copy;
70a4568f 2151 vnc_hextile_set_pixel_conversion(vs, 0);
6cec5487
AL
2152 } else {
2153 vs->write_pixels = vnc_write_pixels_generic;
70a4568f 2154 vnc_hextile_set_pixel_conversion(vs, 1);
6cec5487
AL
2155 }
2156}
2157
0c426e45
AG
2158static void send_color_map(VncState *vs)
2159{
2160 int i;
2161
2162 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2163 vnc_write_u8(vs, 0); /* padding */
2164 vnc_write_u16(vs, 0); /* first color */
2165 vnc_write_u16(vs, 256); /* # of colors */
2166
2167 for (i = 0; i < 256; i++) {
2168 PixelFormat *pf = &vs->client_pf;
2169
2170 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2171 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2172 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2173 }
2174}
2175
ec9fb41a 2176static void set_pixel_format(VncState *vs, int bits_per_pixel,
28a76be8
AL
2177 int big_endian_flag, int true_color_flag,
2178 int red_max, int green_max, int blue_max,
2179 int red_shift, int green_shift, int blue_shift)
24236869 2180{
3512779a 2181 if (!true_color_flag) {
0c426e45
AG
2182 /* Expose a reasonable default 256 color map */
2183 bits_per_pixel = 8;
0c426e45
AG
2184 red_max = 7;
2185 green_max = 7;
2186 blue_max = 3;
2187 red_shift = 0;
2188 green_shift = 3;
2189 blue_shift = 6;
3512779a 2190 }
24236869 2191
e6908bfe
PM
2192 switch (bits_per_pixel) {
2193 case 8:
2194 case 16:
2195 case 32:
2196 break;
2197 default:
2198 vnc_client_error(vs);
2199 return;
2200 }
2201
4c65fed8 2202 vs->client_pf.rmax = red_max ? red_max : 0xFF;
7c9209e7 2203 vs->client_pf.rbits = ctpopl(red_max);
9f64916d
GH
2204 vs->client_pf.rshift = red_shift;
2205 vs->client_pf.rmask = red_max << red_shift;
4c65fed8 2206 vs->client_pf.gmax = green_max ? green_max : 0xFF;
7c9209e7 2207 vs->client_pf.gbits = ctpopl(green_max);
9f64916d
GH
2208 vs->client_pf.gshift = green_shift;
2209 vs->client_pf.gmask = green_max << green_shift;
4c65fed8 2210 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
7c9209e7 2211 vs->client_pf.bbits = ctpopl(blue_max);
9f64916d
GH
2212 vs->client_pf.bshift = blue_shift;
2213 vs->client_pf.bmask = blue_max << blue_shift;
2214 vs->client_pf.bits_per_pixel = bits_per_pixel;
2215 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2216 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2217 vs->client_be = big_endian_flag;
6cec5487 2218
0c426e45
AG
2219 if (!true_color_flag) {
2220 send_color_map(vs);
2221 }
2222
6cec5487 2223 set_pixel_conversion(vs);
24236869 2224
1d0d59fe
GH
2225 graphic_hw_invalidate(vs->vd->dcl.con);
2226 graphic_hw_update(vs->vd->dcl.con);
24236869
FB
2227}
2228
ca4cca4d
AL
2229static void pixel_format_message (VncState *vs) {
2230 char pad[3] = { 0, 0, 0 };
2231
9f64916d
GH
2232 vs->client_pf = qemu_default_pixelformat(32);
2233
2234 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2235 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
ca4cca4d 2236
e2542fe2 2237#ifdef HOST_WORDS_BIGENDIAN
ca4cca4d
AL
2238 vnc_write_u8(vs, 1); /* big-endian-flag */
2239#else
2240 vnc_write_u8(vs, 0); /* big-endian-flag */
2241#endif
2242 vnc_write_u8(vs, 1); /* true-color-flag */
9f64916d
GH
2243 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2244 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2245 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2246 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2247 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2248 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2249 vnc_write(vs, pad, 3); /* padding */
70a4568f
CC
2250
2251 vnc_hextile_set_pixel_conversion(vs, 0);
ca4cca4d 2252 vs->write_pixels = vnc_write_pixels_copy;
ca4cca4d
AL
2253}
2254
753b4053 2255static void vnc_colordepth(VncState *vs)
7eac3a87 2256{
753b4053 2257 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
ca4cca4d 2258 /* Sending a WMVi message to notify the client*/
bd023f95 2259 vnc_lock_output(vs);
46a183da 2260 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
ca4cca4d
AL
2261 vnc_write_u8(vs, 0);
2262 vnc_write_u16(vs, 1); /* number of rects */
d39fa6d8 2263 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2264 pixman_image_get_width(vs->vd->server),
2265 pixman_image_get_height(vs->vd->server),
d39fa6d8 2266 VNC_ENCODING_WMVi);
ca4cca4d 2267 pixel_format_message(vs);
bd023f95 2268 vnc_unlock_output(vs);
ca4cca4d 2269 vnc_flush(vs);
7eac3a87 2270 } else {
6cec5487 2271 set_pixel_conversion(vs);
7eac3a87
AL
2272 }
2273}
2274
60fe76f3 2275static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
24236869
FB
2276{
2277 int i;
2278 uint16_t limit;
2430ffe4
SS
2279 VncDisplay *vd = vs->vd;
2280
2281 if (data[0] > 3) {
0f7b2864 2282 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2430ffe4 2283 }
24236869
FB
2284
2285 switch (data[0]) {
46a183da 2286 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
28a76be8
AL
2287 if (len == 1)
2288 return 20;
2289
ec9fb41a 2290 set_pixel_format(vs, read_u8(data, 4),
28a76be8
AL
2291 read_u8(data, 6), read_u8(data, 7),
2292 read_u16(data, 8), read_u16(data, 10),
2293 read_u16(data, 12), read_u8(data, 14),
2294 read_u8(data, 15), read_u8(data, 16));
2295 break;
46a183da 2296 case VNC_MSG_CLIENT_SET_ENCODINGS:
28a76be8
AL
2297 if (len == 1)
2298 return 4;
24236869 2299
28a76be8 2300 if (len == 4) {
69dd5c9f
AL
2301 limit = read_u16(data, 2);
2302 if (limit > 0)
2303 return 4 + (limit * 4);
2304 } else
2305 limit = read_u16(data, 2);
24236869 2306
28a76be8
AL
2307 for (i = 0; i < limit; i++) {
2308 int32_t val = read_s32(data, 4 + (i * 4));
2309 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2310 }
24236869 2311
28a76be8
AL
2312 set_encodings(vs, (int32_t *)(data + 4), limit);
2313 break;
46a183da 2314 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
28a76be8
AL
2315 if (len == 1)
2316 return 10;
24236869 2317
28a76be8
AL
2318 framebuffer_update_request(vs,
2319 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2320 read_u16(data, 6), read_u16(data, 8));
2321 break;
46a183da 2322 case VNC_MSG_CLIENT_KEY_EVENT:
28a76be8
AL
2323 if (len == 1)
2324 return 8;
24236869 2325
28a76be8
AL
2326 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2327 break;
46a183da 2328 case VNC_MSG_CLIENT_POINTER_EVENT:
28a76be8
AL
2329 if (len == 1)
2330 return 6;
24236869 2331
28a76be8
AL
2332 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2333 break;
46a183da 2334 case VNC_MSG_CLIENT_CUT_TEXT:
f9a70e79 2335 if (len == 1) {
28a76be8 2336 return 8;
f9a70e79 2337 }
28a76be8 2338 if (len == 8) {
baa7666c 2339 uint32_t dlen = read_u32(data, 4);
f9a70e79
PL
2340 if (dlen > (1 << 20)) {
2341 error_report("vnc: client_cut_text msg payload has %u bytes"
2342 " which exceeds our limit of 1MB.", dlen);
2343 vnc_client_error(vs);
2344 break;
2345 }
2346 if (dlen > 0) {
baa7666c 2347 return 8 + dlen;
f9a70e79 2348 }
baa7666c 2349 }
24236869 2350
28a76be8
AL
2351 client_cut_text(vs, read_u32(data, 4), data + 8);
2352 break;
46a183da 2353 case VNC_MSG_CLIENT_QEMU:
9ca313aa
AL
2354 if (len == 1)
2355 return 2;
2356
2357 switch (read_u8(data, 1)) {
46a183da 2358 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
9ca313aa
AL
2359 if (len == 2)
2360 return 12;
2361
2362 ext_key_event(vs, read_u16(data, 2),
2363 read_u32(data, 4), read_u32(data, 8));
2364 break;
46a183da 2365 case VNC_MSG_CLIENT_QEMU_AUDIO:
429a8ed3 2366 if (len == 2)
2367 return 4;
2368
2369 switch (read_u16 (data, 2)) {
46a183da 2370 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
429a8ed3 2371 audio_add(vs);
2372 break;
46a183da 2373 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
429a8ed3 2374 audio_del(vs);
2375 break;
46a183da 2376 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
429a8ed3 2377 if (len == 4)
2378 return 10;
2379 switch (read_u8(data, 4)) {
2380 case 0: vs->as.fmt = AUD_FMT_U8; break;
2381 case 1: vs->as.fmt = AUD_FMT_S8; break;
2382 case 2: vs->as.fmt = AUD_FMT_U16; break;
2383 case 3: vs->as.fmt = AUD_FMT_S16; break;
2384 case 4: vs->as.fmt = AUD_FMT_U32; break;
2385 case 5: vs->as.fmt = AUD_FMT_S32; break;
2386 default:
153130cd 2387 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
429a8ed3 2388 vnc_client_error(vs);
2389 break;
2390 }
2391 vs->as.nchannels = read_u8(data, 5);
2392 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
090fdc83 2393 VNC_DEBUG("Invalid audio channel count %d\n",
153130cd 2394 read_u8(data, 5));
429a8ed3 2395 vnc_client_error(vs);
2396 break;
2397 }
2398 vs->as.freq = read_u32(data, 6);
2399 break;
2400 default:
153130cd 2401 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
429a8ed3 2402 vnc_client_error(vs);
2403 break;
2404 }
2405 break;
2406
9ca313aa 2407 default:
153130cd 2408 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
9ca313aa
AL
2409 vnc_client_error(vs);
2410 break;
2411 }
2412 break;
24236869 2413 default:
153130cd 2414 VNC_DEBUG("Msg: %d\n", data[0]);
28a76be8
AL
2415 vnc_client_error(vs);
2416 break;
24236869 2417 }
5fafdf24 2418
e2b72cb6 2419 vnc_update_throttle_offset(vs);
24236869
FB
2420 vnc_read_when(vs, protocol_client_msg, 1);
2421 return 0;
2422}
2423
60fe76f3 2424static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869 2425{
c35734b2 2426 char buf[1024];
8cf36489 2427 VncShareMode mode;
c35734b2 2428 int size;
24236869 2429
8cf36489
GH
2430 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2431 switch (vs->vd->share_policy) {
2432 case VNC_SHARE_POLICY_IGNORE:
2433 /*
2434 * Ignore the shared flag. Nothing to do here.
2435 *
2436 * Doesn't conform to the rfb spec but is traditional qemu
2437 * behavior, thus left here as option for compatibility
2438 * reasons.
2439 */
2440 break;
2441 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2442 /*
2443 * Policy: Allow clients ask for exclusive access.
2444 *
2445 * Implementation: When a client asks for exclusive access,
2446 * disconnect all others. Shared connects are allowed as long
2447 * as no exclusive connection exists.
2448 *
2449 * This is how the rfb spec suggests to handle the shared flag.
2450 */
2451 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2452 VncState *client;
2453 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2454 if (vs == client) {
2455 continue;
2456 }
2457 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2458 client->share_mode != VNC_SHARE_MODE_SHARED) {
2459 continue;
2460 }
2461 vnc_disconnect_start(client);
2462 }
2463 }
2464 if (mode == VNC_SHARE_MODE_SHARED) {
2465 if (vs->vd->num_exclusive > 0) {
2466 vnc_disconnect_start(vs);
2467 return 0;
2468 }
2469 }
2470 break;
2471 case VNC_SHARE_POLICY_FORCE_SHARED:
2472 /*
2473 * Policy: Shared connects only.
2474 * Implementation: Disallow clients asking for exclusive access.
2475 *
2476 * Useful for shared desktop sessions where you don't want
2477 * someone forgetting to say -shared when running the vnc
2478 * client disconnect everybody else.
2479 */
2480 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2481 vnc_disconnect_start(vs);
2482 return 0;
2483 }
2484 break;
2485 }
2486 vnc_set_share_mode(vs, mode);
2487
e5f34cdd
GH
2488 if (vs->vd->num_shared > vs->vd->connections_limit) {
2489 vnc_disconnect_start(vs);
2490 return 0;
2491 }
2492
bea60dd7
PL
2493 vs->client_width = pixman_image_get_width(vs->vd->server);
2494 vs->client_height = pixman_image_get_height(vs->vd->server);
5862d195
GH
2495 vnc_write_u16(vs, vs->client_width);
2496 vnc_write_u16(vs, vs->client_height);
24236869 2497
ca4cca4d 2498 pixel_format_message(vs);
24236869 2499
97efe4f9 2500 if (qemu_name) {
c35734b2 2501 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
97efe4f9
TH
2502 if (size > sizeof(buf)) {
2503 size = sizeof(buf);
2504 }
2505 } else {
c35734b2 2506 size = snprintf(buf, sizeof(buf), "QEMU");
97efe4f9 2507 }
c35734b2
TS
2508
2509 vnc_write_u32(vs, size);
2510 vnc_write(vs, buf, size);
24236869
FB
2511 vnc_flush(vs);
2512
4a80dba3 2513 vnc_client_cache_auth(vs);
fb6ba0d5 2514 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
4a80dba3 2515
24236869
FB
2516 vnc_read_when(vs, protocol_client_msg, 1);
2517
2518 return 0;
2519}
2520
5fb6c7a8
AL
2521void start_client_init(VncState *vs)
2522{
2523 vnc_read_when(vs, protocol_client_init, 1);
2524}
2525
70848515
TS
2526static void make_challenge(VncState *vs)
2527{
2528 int i;
2529
2530 srand(time(NULL)+getpid()+getpid()*987654+rand());
2531
2532 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2533 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2534}
2535
60fe76f3 2536static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 2537{
60fe76f3 2538 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
800567a6 2539 size_t i, pwlen;
60fe76f3 2540 unsigned char key[8];
3c9405a0 2541 time_t now = time(NULL);
60928458 2542 QCryptoCipher *cipher = NULL;
800567a6 2543 Error *err = NULL;
70848515 2544
1cd20f8b 2545 if (!vs->vd->password) {
7364dbda 2546 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
6bffdf0f 2547 goto reject;
70848515 2548 }
3c9405a0 2549 if (vs->vd->expires < now) {
7364dbda 2550 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
3c9405a0
GH
2551 goto reject;
2552 }
70848515
TS
2553
2554 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2555
2556 /* Calculate the expected challenge response */
753b4053 2557 pwlen = strlen(vs->vd->password);
70848515 2558 for (i=0; i<sizeof(key); i++)
753b4053 2559 key[i] = i<pwlen ? vs->vd->password[i] : 0;
800567a6
DB
2560
2561 cipher = qcrypto_cipher_new(
2562 QCRYPTO_CIPHER_ALG_DES_RFB,
2563 QCRYPTO_CIPHER_MODE_ECB,
2564 key, G_N_ELEMENTS(key),
2565 &err);
2566 if (!cipher) {
7364dbda
DB
2567 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2568 error_get_pretty(err));
800567a6
DB
2569 error_free(err);
2570 goto reject;
2571 }
2572
a1695137 2573 if (qcrypto_cipher_encrypt(cipher,
800567a6
DB
2574 vs->challenge,
2575 response,
2576 VNC_AUTH_CHALLENGE_SIZE,
2577 &err) < 0) {
7364dbda
DB
2578 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2579 error_get_pretty(err));
800567a6
DB
2580 error_free(err);
2581 goto reject;
2582 }
70848515
TS
2583
2584 /* Compare expected vs actual challenge response */
2585 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
7364dbda 2586 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
6bffdf0f 2587 goto reject;
70848515 2588 } else {
7364dbda 2589 trace_vnc_auth_pass(vs, vs->auth);
28a76be8
AL
2590 vnc_write_u32(vs, 0); /* Accept auth */
2591 vnc_flush(vs);
70848515 2592
5fb6c7a8 2593 start_client_init(vs);
70848515 2594 }
60928458
GA
2595
2596 qcrypto_cipher_free(cipher);
70848515 2597 return 0;
6bffdf0f
GH
2598
2599reject:
2600 vnc_write_u32(vs, 1); /* Reject auth */
2601 if (vs->minor >= 8) {
2602 static const char err[] = "Authentication failed";
2603 vnc_write_u32(vs, sizeof(err));
2604 vnc_write(vs, err, sizeof(err));
2605 }
2606 vnc_flush(vs);
2607 vnc_client_error(vs);
60928458 2608 qcrypto_cipher_free(cipher);
6bffdf0f 2609 return 0;
70848515
TS
2610}
2611
5fb6c7a8 2612void start_auth_vnc(VncState *vs)
70848515
TS
2613{
2614 make_challenge(vs);
2615 /* Send client a 'random' challenge */
2616 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2617 vnc_flush(vs);
2618
2619 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
469b15c6
TS
2620}
2621
2622
60fe76f3 2623static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
2624{
2625 /* We only advertise 1 auth scheme at a time, so client
2626 * must pick the one we sent. Verify this */
7e7e2ebc 2627 if (data[0] != vs->auth) { /* Reject auth */
7364dbda 2628 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
70848515
TS
2629 vnc_write_u32(vs, 1);
2630 if (vs->minor >= 8) {
2631 static const char err[] = "Authentication failed";
2632 vnc_write_u32(vs, sizeof(err));
2633 vnc_write(vs, err, sizeof(err));
2634 }
2635 vnc_client_error(vs);
2636 } else { /* Accept requested auth */
7364dbda 2637 trace_vnc_auth_start(vs, vs->auth);
7e7e2ebc 2638 switch (vs->auth) {
70848515 2639 case VNC_AUTH_NONE:
a26c97ad
AZ
2640 if (vs->minor >= 8) {
2641 vnc_write_u32(vs, 0); /* Accept auth completion */
2642 vnc_flush(vs);
2643 }
7364dbda 2644 trace_vnc_auth_pass(vs, vs->auth);
5fb6c7a8 2645 start_client_init(vs);
70848515
TS
2646 break;
2647
2648 case VNC_AUTH_VNC:
5fb6c7a8
AL
2649 start_auth_vnc(vs);
2650 break;
70848515 2651
8d5d2d4c 2652 case VNC_AUTH_VENCRYPT:
5fb6c7a8
AL
2653 start_auth_vencrypt(vs);
2654 break;
8d5d2d4c 2655
2f9606b3
AL
2656#ifdef CONFIG_VNC_SASL
2657 case VNC_AUTH_SASL:
2f9606b3
AL
2658 start_auth_sasl(vs);
2659 break;
2660#endif /* CONFIG_VNC_SASL */
2661
70848515 2662 default: /* Should not be possible, but just in case */
7364dbda 2663 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
70848515
TS
2664 vnc_write_u8(vs, 1);
2665 if (vs->minor >= 8) {
2666 static const char err[] = "Authentication failed";
2667 vnc_write_u32(vs, sizeof(err));
2668 vnc_write(vs, err, sizeof(err));
2669 }
2670 vnc_client_error(vs);
2671 }
2672 }
2673 return 0;
2674}
2675
60fe76f3 2676static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
2677{
2678 char local[13];
24236869
FB
2679
2680 memcpy(local, version, 12);
2681 local[12] = 0;
2682
70848515 2683 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
28a76be8
AL
2684 VNC_DEBUG("Malformed protocol version %s\n", local);
2685 vnc_client_error(vs);
2686 return 0;
24236869 2687 }
70848515
TS
2688 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2689 if (vs->major != 3 ||
28a76be8
AL
2690 (vs->minor != 3 &&
2691 vs->minor != 4 &&
2692 vs->minor != 5 &&
2693 vs->minor != 7 &&
2694 vs->minor != 8)) {
2695 VNC_DEBUG("Unsupported client version\n");
2696 vnc_write_u32(vs, VNC_AUTH_INVALID);
2697 vnc_flush(vs);
2698 vnc_client_error(vs);
2699 return 0;
70848515 2700 }
b0566f4f 2701 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
2702 * as equivalent to v3.3 by servers
2703 */
b0566f4f 2704 if (vs->minor == 4 || vs->minor == 5)
28a76be8 2705 vs->minor = 3;
70848515
TS
2706
2707 if (vs->minor == 3) {
7364dbda 2708 trace_vnc_auth_start(vs, vs->auth);
7e7e2ebc 2709 if (vs->auth == VNC_AUTH_NONE) {
7e7e2ebc 2710 vnc_write_u32(vs, vs->auth);
70848515 2711 vnc_flush(vs);
7364dbda 2712 trace_vnc_auth_pass(vs, vs->auth);
28a76be8 2713 start_client_init(vs);
7e7e2ebc 2714 } else if (vs->auth == VNC_AUTH_VNC) {
70848515 2715 VNC_DEBUG("Tell client VNC auth\n");
7e7e2ebc 2716 vnc_write_u32(vs, vs->auth);
70848515
TS
2717 vnc_flush(vs);
2718 start_auth_vnc(vs);
2719 } else {
7364dbda
DB
2720 trace_vnc_auth_fail(vs, vs->auth,
2721 "Unsupported auth method for v3.3", "");
70848515
TS
2722 vnc_write_u32(vs, VNC_AUTH_INVALID);
2723 vnc_flush(vs);
2724 vnc_client_error(vs);
2725 }
2726 } else {
28a76be8 2727 vnc_write_u8(vs, 1); /* num auth */
7e7e2ebc 2728 vnc_write_u8(vs, vs->auth);
28a76be8
AL
2729 vnc_read_when(vs, protocol_client_auth, 1);
2730 vnc_flush(vs);
70848515 2731 }
24236869
FB
2732
2733 return 0;
2734}
2735
999342a0
CC
2736static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2737{
2738 struct VncSurface *vs = &vd->guest;
2739
2740 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2741}
2742
7d964c9d
CC
2743void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2744{
2745 int i, j;
2746
2747 w = (x + w) / VNC_STAT_RECT;
2748 h = (y + h) / VNC_STAT_RECT;
2749 x /= VNC_STAT_RECT;
2750 y /= VNC_STAT_RECT;
2751
207f328a
CC
2752 for (j = y; j <= h; j++) {
2753 for (i = x; i <= w; i++) {
7d964c9d
CC
2754 vs->lossy_rect[j][i] = 1;
2755 }
2756 }
2757}
2758
2759static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2760{
2761 VncState *vs;
2762 int sty = y / VNC_STAT_RECT;
2763 int stx = x / VNC_STAT_RECT;
2764 int has_dirty = 0;
2765
5a3804db
MAL
2766 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2767 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
7d964c9d
CC
2768
2769 QTAILQ_FOREACH(vs, &vd->clients, next) {
bc2429b9 2770 int j;
7d964c9d
CC
2771
2772 /* kernel send buffers are full -> refresh later */
2773 if (vs->output.offset) {
2774 continue;
2775 }
2776
2777 if (!vs->lossy_rect[sty][stx]) {
2778 continue;
2779 }
207f328a 2780
7d964c9d
CC
2781 vs->lossy_rect[sty][stx] = 0;
2782 for (j = 0; j < VNC_STAT_RECT; ++j) {
b4c85ddc
PL
2783 bitmap_set(vs->dirty[y + j],
2784 x / VNC_DIRTY_PIXELS_PER_BIT,
2785 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
7d964c9d
CC
2786 }
2787 has_dirty++;
2788 }
207f328a 2789
7d964c9d
CC
2790 return has_dirty;
2791}
2792
2793static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
999342a0 2794{
eebe0b79
GH
2795 int width = MIN(pixman_image_get_width(vd->guest.fb),
2796 pixman_image_get_width(vd->server));
2797 int height = MIN(pixman_image_get_height(vd->guest.fb),
2798 pixman_image_get_height(vd->server));
999342a0
CC
2799 int x, y;
2800 struct timeval res;
7d964c9d 2801 int has_dirty = 0;
999342a0 2802
9f64916d
GH
2803 for (y = 0; y < height; y += VNC_STAT_RECT) {
2804 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
2805 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2806
2807 rect->updated = false;
2808 }
2809 }
2810
ad620c29 2811 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
999342a0
CC
2812
2813 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
7d964c9d 2814 return has_dirty;
999342a0
CC
2815 }
2816 vd->guest.last_freq_check = *tv;
2817
9f64916d
GH
2818 for (y = 0; y < height; y += VNC_STAT_RECT) {
2819 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
2820 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2821 int count = ARRAY_SIZE(rect->times);
2822 struct timeval min, max;
2823
2824 if (!timerisset(&rect->times[count - 1])) {
2825 continue ;
2826 }
2827
2828 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 2829 qemu_timersub(tv, &max, &res);
999342a0
CC
2830
2831 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2832 rect->freq = 0;
7d964c9d 2833 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
999342a0
CC
2834 memset(rect->times, 0, sizeof (rect->times));
2835 continue ;
2836 }
2837
2838 min = rect->times[rect->idx];
2839 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 2840 qemu_timersub(&max, &min, &res);
999342a0
CC
2841
2842 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2843 rect->freq /= count;
2844 rect->freq = 1. / rect->freq;
2845 }
2846 }
7d964c9d 2847 return has_dirty;
999342a0
CC
2848}
2849
2850double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2851{
2852 int i, j;
2853 double total = 0;
2854 int num = 0;
2855
5a3804db
MAL
2856 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2857 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
999342a0
CC
2858
2859 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2860 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2861 total += vnc_stat_rect(vs->vd, i, j)->freq;
2862 num++;
2863 }
2864 }
2865
2866 if (num) {
2867 return total / num;
2868 } else {
2869 return 0;
2870 }
2871}
2872
2873static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2874{
2875 VncRectStat *rect;
2876
2877 rect = vnc_stat_rect(vd, x, y);
2878 if (rect->updated) {
2879 return ;
2880 }
2881 rect->times[rect->idx] = *tv;
2882 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2883 rect->updated = true;
2884}
2885
1fc62412
SS
2886static int vnc_refresh_server_surface(VncDisplay *vd)
2887{
bea60dd7
PL
2888 int width = MIN(pixman_image_get_width(vd->guest.fb),
2889 pixman_image_get_width(vd->server));
2890 int height = MIN(pixman_image_get_height(vd->guest.fb),
2891 pixman_image_get_height(vd->server));
eb8934b0 2892 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
12b316d4 2893 uint8_t *guest_row0 = NULL, *server_row0;
41b4bef6 2894 VncState *vs;
1fc62412 2895 int has_dirty = 0;
9f64916d 2896 pixman_image_t *tmpbuf = NULL;
1fc62412 2897
80e0c8c3 2898 struct timeval tv = { 0, 0 };
999342a0 2899
80e0c8c3
CC
2900 if (!vd->non_adaptive) {
2901 gettimeofday(&tv, NULL);
2902 has_dirty = vnc_update_stats(vd, &tv);
2903 }
999342a0 2904
1fc62412
SS
2905 /*
2906 * Walk through the guest dirty map.
2907 * Check and copy modified bits from guest to server surface.
2908 * Update server dirty map.
2909 */
bea60dd7 2910 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
eb8934b0
GH
2911 server_stride = guest_stride = guest_ll =
2912 pixman_image_get_stride(vd->server);
bea60dd7
PL
2913 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2914 server_stride);
9f64916d
GH
2915 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2916 int width = pixman_image_get_width(vd->server);
2917 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
12b316d4 2918 } else {
eb8934b0
GH
2919 int guest_bpp =
2920 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
12b316d4
PL
2921 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2922 guest_stride = pixman_image_get_stride(vd->guest.fb);
659c90ee 2923 guest_ll = pixman_image_get_width(vd->guest.fb) * (DIV_ROUND_UP(guest_bpp, 8));
12b316d4 2924 }
eb8934b0 2925 line_bytes = MIN(server_stride, guest_ll);
12b316d4 2926
12b316d4
PL
2927 for (;;) {
2928 int x;
2929 uint8_t *guest_ptr, *server_ptr;
2930 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2931 height * VNC_DIRTY_BPL(&vd->guest),
2932 y * VNC_DIRTY_BPL(&vd->guest));
2933 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2934 /* no more dirty bits */
2935 break;
2936 }
2937 y = offset / VNC_DIRTY_BPL(&vd->guest);
2938 x = offset % VNC_DIRTY_BPL(&vd->guest);
1fc62412 2939
12b316d4
PL
2940 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2941
2942 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2943 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2944 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2945 } else {
2946 guest_ptr = guest_row0 + y * guest_stride;
2947 }
2948 guest_ptr += x * cmp_bytes;
2949
2950 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2951 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
bea60dd7 2952 int _cmp_bytes = cmp_bytes;
12b316d4
PL
2953 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2954 continue;
2955 }
eb8934b0
GH
2956 if ((x + 1) * cmp_bytes > line_bytes) {
2957 _cmp_bytes = line_bytes - x * cmp_bytes;
bea60dd7 2958 }
eb8934b0 2959 assert(_cmp_bytes >= 0);
bea60dd7 2960 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
12b316d4
PL
2961 continue;
2962 }
bea60dd7 2963 memcpy(server_ptr, guest_ptr, _cmp_bytes);
12b316d4
PL
2964 if (!vd->non_adaptive) {
2965 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2966 y, &tv);
1fc62412 2967 }
12b316d4
PL
2968 QTAILQ_FOREACH(vs, &vd->clients, next) {
2969 set_bit(x, vs->dirty[y]);
2970 }
2971 has_dirty++;
1fc62412 2972 }
12b316d4
PL
2973
2974 y++;
1fc62412 2975 }
9f64916d 2976 qemu_pixman_image_unref(tmpbuf);
1fc62412
SS
2977 return has_dirty;
2978}
2979
0f7b2864 2980static void vnc_refresh(DisplayChangeListener *dcl)
703bc68f 2981{
0f7b2864 2982 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
41b4bef6
AS
2983 VncState *vs, *vn;
2984 int has_dirty, rects = 0;
703bc68f 2985
9d6b2070
C
2986 if (QTAILQ_EMPTY(&vd->clients)) {
2987 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
2988 return;
2989 }
2990
1d0d59fe 2991 graphic_hw_update(vd->dcl.con);
703bc68f 2992
bd023f95 2993 if (vnc_trylock_display(vd)) {
0f7b2864 2994 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
bd023f95
CC
2995 return;
2996 }
2997
1fc62412 2998 has_dirty = vnc_refresh_server_surface(vd);
bd023f95 2999 vnc_unlock_display(vd);
1fc62412 3000
41b4bef6 3001 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
6af998db 3002 rects += vnc_update_client(vs, has_dirty);
6185c578 3003 /* vs might be free()ed here */
703bc68f 3004 }
bd023f95 3005
2430ffe4 3006 if (has_dirty && rects) {
0f7b2864
GH
3007 vd->dcl.update_interval /= 2;
3008 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
3009 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3010 }
2430ffe4 3011 } else {
0f7b2864
GH
3012 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3013 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3014 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3015 }
703bc68f
SS
3016 }
3017}
3018
04d2529d 3019static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2c8cf549 3020 bool skipauth, bool websocket)
3aa3eea3 3021{
fedf0d35 3022 VncState *vs = g_new0(VncState, 1);
90cd03a3 3023 bool first_client = QTAILQ_EMPTY(&vd->clients);
7d964c9d
CC
3024 int i;
3025
ad6374c4 3026 trace_vnc_client_connect(vs, sioc);
04d2529d
DB
3027 vs->sioc = sioc;
3028 object_ref(OBJECT(vs->sioc));
3029 vs->ioc = QIO_CHANNEL(sioc);
3030 object_ref(OBJECT(vs->ioc));
d616ccc5 3031 vs->vd = vd;
7e7e2ebc 3032
04d2529d
DB
3033 buffer_init(&vs->input, "vnc-input/%p", sioc);
3034 buffer_init(&vs->output, "vnc-output/%p", sioc);
04d2529d 3035 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
543b9580 3036
04d2529d
DB
3037 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
3038 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
3039 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
543b9580 3040#ifdef CONFIG_VNC_JPEG
04d2529d 3041 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
543b9580
GH
3042#endif
3043#ifdef CONFIG_VNC_PNG
04d2529d 3044 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
543b9580 3045#endif
04d2529d
DB
3046 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
3047 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
3048 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
3049 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
543b9580 3050
7e7e2ebc
DB
3051 if (skipauth) {
3052 vs->auth = VNC_AUTH_NONE;
7e7e2ebc 3053 vs->subauth = VNC_AUTH_INVALID;
7e7e2ebc 3054 } else {
f9148c8a
DB
3055 if (websocket) {
3056 vs->auth = vd->ws_auth;
3057 vs->subauth = VNC_AUTH_INVALID;
3058 } else {
3059 vs->auth = vd->auth;
3060 vs->subauth = vd->subauth;
3061 }
7e7e2ebc 3062 }
04d2529d
DB
3063 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3064 sioc, websocket, vs->auth, vs->subauth);
7e7e2ebc 3065
7267c094 3066 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
7d964c9d 3067 for (i = 0; i < VNC_STAT_ROWS; ++i) {
fedf0d35 3068 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
7d964c9d 3069 }
753b4053 3070
04d2529d 3071 VNC_DEBUG("New client on socket %p\n", vs->sioc);
0f7b2864 3072 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
04d2529d 3073 qio_channel_set_blocking(vs->ioc, false, NULL);
a75d6f07
BC
3074 if (vs->ioc_tag) {
3075 g_source_remove(vs->ioc_tag);
3076 }
7536ee4b
TH
3077 if (websocket) {
3078 vs->websocket = 1;
38e5756a 3079 if (vd->tlscreds) {
04d2529d
DB
3080 vs->ioc_tag = qio_channel_add_watch(
3081 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3e305e4a 3082 } else {
04d2529d
DB
3083 vs->ioc_tag = qio_channel_add_watch(
3084 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
0057a0d5 3085 }
04d2529d
DB
3086 } else {
3087 vs->ioc_tag = qio_channel_add_watch(
3088 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
7536ee4b 3089 }
753b4053 3090
4a80dba3 3091 vnc_client_cache_addr(vs);
fb6ba0d5 3092 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
8cf36489 3093 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
4a80dba3 3094
753b4053
AL
3095 vs->last_x = -1;
3096 vs->last_y = -1;
3097
3098 vs->as.freq = 44100;
3099 vs->as.nchannels = 2;
3100 vs->as.fmt = AUD_FMT_S16;
3101 vs->as.endianness = 0;
3102
bd023f95 3103 qemu_mutex_init(&vs->output_mutex);
175b2a6e 3104 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
bd023f95 3105
e5f34cdd 3106 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
c7628bff
GH
3107 if (first_client) {
3108 vnc_update_server_surface(vd);
3109 }
1fc62412 3110
1d0d59fe 3111 graphic_hw_update(vd->dcl.con);
1fc62412 3112
90cd03a3 3113 if (!vs->websocket) {
dbee9897 3114 vnc_start_protocol(vs);
90cd03a3
DB
3115 }
3116
3117 if (vd->num_connecting > vd->connections_limit) {
3118 QTAILQ_FOREACH(vs, &vd->clients, next) {
3119 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3120 vnc_disconnect_start(vs);
3121 return;
3122 }
3123 }
3124 }
3125}
3126
dbee9897 3127void vnc_start_protocol(VncState *vs)
90cd03a3 3128{
3aa3eea3
AZ
3129 vnc_write(vs, "RFB 003.008\n", 12);
3130 vnc_flush(vs);
3131 vnc_read_when(vs, protocol_version, 12);
753b4053 3132
37c34d9d
AL
3133 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3134 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3aa3eea3
AZ
3135}
3136
04d2529d
DB
3137static gboolean vnc_listen_io(QIOChannel *ioc,
3138 GIOCondition condition,
3139 void *opaque)
24236869 3140{
bf01c179 3141 VncDisplay *vd = opaque;
04d2529d
DB
3142 QIOChannelSocket *sioc = NULL;
3143 Error *err = NULL;
4ee74fa7
DB
3144 bool isWebsock = false;
3145 size_t i;
3146
3147 for (i = 0; i < vd->nlwebsock; i++) {
3148 if (ioc == QIO_CHANNEL(vd->lwebsock[i])) {
3149 isWebsock = true;
3150 break;
3151 }
3152 }
24236869 3153
04d2529d
DB
3154 sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
3155 if (sioc != NULL) {
10bcfe58 3156 qio_channel_set_name(QIO_CHANNEL(sioc),
4ee74fa7 3157 isWebsock ? "vnc-ws-server" : "vnc-server");
04d2529d 3158 qio_channel_set_delay(QIO_CHANNEL(sioc), false);
4ee74fa7 3159 vnc_connect(vd, sioc, false, isWebsock);
04d2529d 3160 object_unref(OBJECT(sioc));
8e9b0d24 3161 } else {
04d2529d
DB
3162 /* client probably closed connection before we got there */
3163 error_free(err);
24236869 3164 }
7536ee4b 3165
04d2529d 3166 return TRUE;
7536ee4b 3167}
7536ee4b 3168
7c20b4a3 3169static const DisplayChangeListenerOps dcl_ops = {
34da30af
BH
3170 .dpy_name = "vnc",
3171 .dpy_refresh = vnc_refresh,
34da30af
BH
3172 .dpy_gfx_update = vnc_dpy_update,
3173 .dpy_gfx_switch = vnc_dpy_switch,
3174 .dpy_gfx_check_format = qemu_pixman_check_format,
3175 .dpy_mouse_set = vnc_mouse_set,
3176 .dpy_cursor_define = vnc_dpy_cursor_define,
7c20b4a3
GH
3177};
3178
14f7143e 3179void vnc_display_init(const char *id)
24236869 3180{
bf01c179 3181 VncDisplay *vd;
4db14629
GH
3182
3183 if (vnc_display_find(id) != NULL) {
3184 return;
3185 }
bf01c179 3186 vd = g_malloc0(sizeof(*vd));
24236869 3187
bf01c179
DB
3188 vd->id = strdup(id);
3189 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
24236869 3190
bf01c179
DB
3191 QTAILQ_INIT(&vd->clients);
3192 vd->expires = TIME_MAX;
24236869 3193
40066175
GH
3194 if (keyboard_layout) {
3195 trace_vnc_key_map_init(keyboard_layout);
bf01c179 3196 vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
40066175 3197 } else {
bf01c179 3198 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
40066175 3199 }
24236869 3200
bf01c179 3201 if (!vd->kbd_layout) {
28a76be8 3202 exit(1);
bf01c179 3203 }
24236869 3204
bf01c179
DB
3205 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3206 vd->connections_limit = 32;
12e29b16 3207
bf01c179 3208 qemu_mutex_init(&vd->mutex);
bd023f95 3209 vnc_start_worker_thread();
bd023f95 3210
bf01c179
DB
3211 vd->dcl.ops = &dcl_ops;
3212 register_displaychangelistener(&vd->dcl);
71cab5ca
TS
3213}
3214
6f43024c 3215
bf01c179 3216static void vnc_display_close(VncDisplay *vd)
71cab5ca 3217{
4ee74fa7 3218 size_t i;
bf01c179 3219 if (!vd) {
452b4d88 3220 return;
bf01c179
DB
3221 }
3222 vd->is_unix = false;
4ee74fa7
DB
3223 for (i = 0; i < vd->nlsock; i++) {
3224 if (vd->lsock_tag[i]) {
3225 g_source_remove(vd->lsock_tag[i]);
04d2529d 3226 }
4ee74fa7 3227 object_unref(OBJECT(vd->lsock[i]));
71cab5ca 3228 }
4ee74fa7
DB
3229 g_free(vd->lsock);
3230 g_free(vd->lsock_tag);
3231 vd->lsock = NULL;
2dc120be 3232 vd->lsock_tag = NULL;
4ee74fa7
DB
3233 vd->nlsock = 0;
3234
3235 for (i = 0; i < vd->nlwebsock; i++) {
3236 if (vd->lwebsock_tag[i]) {
3237 g_source_remove(vd->lwebsock_tag[i]);
04d2529d 3238 }
4ee74fa7 3239 object_unref(OBJECT(vd->lwebsock[i]));
7536ee4b 3240 }
4ee74fa7
DB
3241 g_free(vd->lwebsock);
3242 g_free(vd->lwebsock_tag);
3243 vd->lwebsock = NULL;
2dc120be 3244 vd->lwebsock_tag = NULL;
4ee74fa7
DB
3245 vd->nlwebsock = 0;
3246
bf01c179
DB
3247 vd->auth = VNC_AUTH_INVALID;
3248 vd->subauth = VNC_AUTH_INVALID;
3249 if (vd->tlscreds) {
3250 object_unparent(OBJECT(vd->tlscreds));
3251 vd->tlscreds = NULL;
3e305e4a 3252 }
bf01c179
DB
3253 g_free(vd->tlsaclname);
3254 vd->tlsaclname = NULL;
a54f0d2b
PO
3255 if (vd->lock_key_sync) {
3256 qemu_remove_led_event_handler(vd->led);
2dc120be 3257 vd->led = NULL;
a54f0d2b 3258 }
70848515
TS
3259}
3260
14f7143e 3261int vnc_display_password(const char *id, const char *password)
70848515 3262{
bf01c179 3263 VncDisplay *vd = vnc_display_find(id);
70848515 3264
bf01c179 3265 if (!vd) {
a6aa9d3e 3266 return -EINVAL;
7ef92331 3267 }
bf01c179 3268 if (vd->auth == VNC_AUTH_NONE) {
cf864569 3269 error_printf_unless_qmp("If you want use passwords please enable "
7ea7d36e 3270 "password auth using '-vnc ${dpy},password'.\n");
cf864569 3271 return -EINVAL;
1cd20f8b
AL
3272 }
3273
bf01c179
DB
3274 g_free(vd->password);
3275 vd->password = g_strdup(password);
a6aa9d3e
LC
3276
3277 return 0;
71cab5ca
TS
3278}
3279
14f7143e 3280int vnc_display_pw_expire(const char *id, time_t expires)
3c9405a0 3281{
bf01c179 3282 VncDisplay *vd = vnc_display_find(id);
3c9405a0 3283
bf01c179 3284 if (!vd) {
1643f2b2
GH
3285 return -EINVAL;
3286 }
3287
bf01c179 3288 vd->expires = expires;
3c9405a0
GH
3289 return 0;
3290}
3291
bf01c179 3292static void vnc_display_print_local_addr(VncDisplay *vd)
f92f8afe 3293{
bd269ebc 3294 SocketAddress *addr;
04d2529d 3295 Error *err = NULL;
d616ccc5 3296
4ee74fa7
DB
3297 if (!vd->nlsock) {
3298 return;
3299 }
3300
3301 addr = qio_channel_socket_get_local_address(vd->lsock[0], &err);
04d2529d 3302 if (!addr) {
33df7bf3 3303 return;
04d2529d
DB
3304 }
3305
bd269ebc
MA
3306 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3307 qapi_free_SocketAddress(addr);
33df7bf3 3308 return;
04d2529d 3309 }
33df7bf3 3310 error_printf_unless_qmp("VNC server running on %s:%s\n",
bd269ebc
MA
3311 addr->u.inet.host,
3312 addr->u.inet.port);
3313 qapi_free_SocketAddress(addr);
f92f8afe
AL
3314}
3315
4db14629
GH
3316static QemuOptsList qemu_vnc_opts = {
3317 .name = "vnc",
3318 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3319 .implied_opt_name = "vnc",
3320 .desc = {
3321 {
3322 .name = "vnc",
3323 .type = QEMU_OPT_STRING,
3324 },{
3325 .name = "websocket",
3326 .type = QEMU_OPT_STRING,
3327 },{
3e305e4a
DB
3328 .name = "tls-creds",
3329 .type = QEMU_OPT_STRING,
3330 },{
3331 /* Deprecated in favour of tls-creds */
4db14629
GH
3332 .name = "x509",
3333 .type = QEMU_OPT_STRING,
3334 },{
3335 .name = "share",
3336 .type = QEMU_OPT_STRING,
1d0d59fe
GH
3337 },{
3338 .name = "display",
3339 .type = QEMU_OPT_STRING,
3340 },{
3341 .name = "head",
3342 .type = QEMU_OPT_NUMBER,
e5f34cdd
GH
3343 },{
3344 .name = "connections",
3345 .type = QEMU_OPT_NUMBER,
88428b7a
GA
3346 },{
3347 .name = "to",
3348 .type = QEMU_OPT_NUMBER,
3349 },{
3350 .name = "ipv4",
3351 .type = QEMU_OPT_BOOL,
3352 },{
3353 .name = "ipv6",
3354 .type = QEMU_OPT_BOOL,
4db14629
GH
3355 },{
3356 .name = "password",
3357 .type = QEMU_OPT_BOOL,
3358 },{
3359 .name = "reverse",
3360 .type = QEMU_OPT_BOOL,
3361 },{
3362 .name = "lock-key-sync",
3363 .type = QEMU_OPT_BOOL,
c5ce8333
GH
3364 },{
3365 .name = "key-delay-ms",
3366 .type = QEMU_OPT_NUMBER,
4db14629
GH
3367 },{
3368 .name = "sasl",
3369 .type = QEMU_OPT_BOOL,
3370 },{
3e305e4a 3371 /* Deprecated in favour of tls-creds */
4db14629
GH
3372 .name = "tls",
3373 .type = QEMU_OPT_BOOL,
3374 },{
3e305e4a 3375 /* Deprecated in favour of tls-creds */
4db14629 3376 .name = "x509verify",
8c7d0645 3377 .type = QEMU_OPT_STRING,
4db14629
GH
3378 },{
3379 .name = "acl",
3380 .type = QEMU_OPT_BOOL,
3381 },{
3382 .name = "lossy",
3383 .type = QEMU_OPT_BOOL,
3384 },{
3385 .name = "non-adaptive",
3386 .type = QEMU_OPT_BOOL,
3387 },
3388 { /* end of list */ }
3389 },
3390};
3391
0dd72e15 3392
3e305e4a 3393static int
eda24e18
DB
3394vnc_display_setup_auth(int *auth,
3395 int *subauth,
3396 QCryptoTLSCreds *tlscreds,
0dd72e15
DB
3397 bool password,
3398 bool sasl,
3e305e4a
DB
3399 bool websocket,
3400 Error **errp)
0dd72e15
DB
3401{
3402 /*
3403 * We have a choice of 3 authentication options
3404 *
3405 * 1. none
3406 * 2. vnc
3407 * 3. sasl
3408 *
3409 * The channel can be run in 2 modes
3410 *
3411 * 1. clear
3412 * 2. tls
3413 *
3414 * And TLS can use 2 types of credentials
3415 *
3416 * 1. anon
3417 * 2. x509
3418 *
3419 * We thus have 9 possible logical combinations
3420 *
3421 * 1. clear + none
3422 * 2. clear + vnc
3423 * 3. clear + sasl
3424 * 4. tls + anon + none
3425 * 5. tls + anon + vnc
3426 * 6. tls + anon + sasl
3427 * 7. tls + x509 + none
3428 * 8. tls + x509 + vnc
3429 * 9. tls + x509 + sasl
3430 *
3431 * These need to be mapped into the VNC auth schemes
3432 * in an appropriate manner. In regular VNC, all the
3433 * TLS options get mapped into VNC_AUTH_VENCRYPT
3434 * sub-auth types.
f9148c8a
DB
3435 *
3436 * In websockets, the https:// protocol already provides
3437 * TLS support, so there is no need to make use of the
3438 * VeNCrypt extension. Furthermore, websockets browser
3439 * clients could not use VeNCrypt even if they wanted to,
3440 * as they cannot control when the TLS handshake takes
3441 * place. Thus there is no option but to rely on https://,
3442 * meaning combinations 4->6 and 7->9 will be mapped to
3443 * VNC auth schemes in the same way as combos 1->3.
3444 *
3445 * Regardless of fact that we have a different mapping to
3446 * VNC auth mechs for plain VNC vs websockets VNC, the end
3447 * result has the same security characteristics.
0dd72e15 3448 */
eda24e18
DB
3449 if (websocket || !tlscreds) {
3450 if (password) {
0dd72e15 3451 VNC_DEBUG("Initializing VNC server with password auth\n");
eda24e18
DB
3452 *auth = VNC_AUTH_VNC;
3453 } else if (sasl) {
3454 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3455 *auth = VNC_AUTH_SASL;
f9148c8a 3456 } else {
eda24e18
DB
3457 VNC_DEBUG("Initializing VNC server with no auth\n");
3458 *auth = VNC_AUTH_NONE;
f9148c8a 3459 }
eda24e18
DB
3460 *subauth = VNC_AUTH_INVALID;
3461 } else {
3462 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3463 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3464 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3465 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3466
3467 if (!is_x509 && !is_anon) {
3468 error_setg(errp,
3469 "Unsupported TLS cred type %s",
3470 object_get_typename(OBJECT(tlscreds)));
3471 return -1;
3472 }
3473 *auth = VNC_AUTH_VENCRYPT;
3474 if (password) {
3475 if (is_x509) {
3476 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3477 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3478 } else {
3479 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3480 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3481 }
3482
3483 } else if (sasl) {
3484 if (is_x509) {
0dd72e15 3485 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
eda24e18 3486 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3e305e4a 3487 } else {
eda24e18
DB
3488 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3489 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
0dd72e15
DB
3490 }
3491 } else {
eda24e18 3492 if (is_x509) {
0dd72e15 3493 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
eda24e18 3494 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3e305e4a 3495 } else {
eda24e18
DB
3496 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3497 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
0dd72e15 3498 }
f9148c8a 3499 }
0dd72e15 3500 }
3e305e4a
DB
3501 return 0;
3502}
3503
3504
3505/*
3506 * Handle back compat with old CLI syntax by creating some
3507 * suitable QCryptoTLSCreds objects
3508 */
3509static QCryptoTLSCreds *
3510vnc_display_create_creds(bool x509,
3511 bool x509verify,
3512 const char *dir,
3513 const char *id,
3514 Error **errp)
3515{
3516 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3517 Object *parent = object_get_objects_root();
3518 Object *creds;
3519 Error *err = NULL;
3520
3521 if (x509) {
3522 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3523 parent,
3524 credsid,
3525 &err,
3526 "endpoint", "server",
3527 "dir", dir,
3528 "verify-peer", x509verify ? "yes" : "no",
3529 NULL);
3530 } else {
3531 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3532 parent,
3533 credsid,
3534 &err,
3535 "endpoint", "server",
3536 NULL);
3537 }
3538
3539 g_free(credsid);
3540
3541 if (err) {
3542 error_propagate(errp, err);
3543 return NULL;
3544 }
3545
3546 return QCRYPTO_TLS_CREDS(creds);
0dd72e15
DB
3547}
3548
3e305e4a 3549
275e0d61
DB
3550static int vnc_display_get_address(const char *addrstr,
3551 bool websocket,
e5766eb4 3552 bool reverse,
275e0d61
DB
3553 int displaynum,
3554 int to,
3555 bool has_ipv4,
3556 bool has_ipv6,
3557 bool ipv4,
3558 bool ipv6,
bd269ebc 3559 SocketAddress **retaddr,
275e0d61
DB
3560 Error **errp)
3561{
3562 int ret = -1;
bd269ebc 3563 SocketAddress *addr = NULL;
275e0d61 3564
bd269ebc 3565 addr = g_new0(SocketAddress, 1);
275e0d61
DB
3566
3567 if (strncmp(addrstr, "unix:", 5) == 0) {
bd269ebc
MA
3568 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3569 addr->u.q_unix.path = g_strdup(addrstr + 5);
275e0d61
DB
3570
3571 if (websocket) {
3572 error_setg(errp, "UNIX sockets not supported with websock");
3573 goto cleanup;
3574 }
3575
3576 if (to) {
3577 error_setg(errp, "Port range not support with UNIX socket");
3578 goto cleanup;
3579 }
3580 ret = 0;
3581 } else {
3582 const char *port;
3583 size_t hostlen;
3584 unsigned long long baseport = 0;
3585 InetSocketAddress *inet;
3586
3587 port = strrchr(addrstr, ':');
3588 if (!port) {
3589 if (websocket) {
3590 hostlen = 0;
3591 port = addrstr;
3592 } else {
3593 error_setg(errp, "no vnc port specified");
3594 goto cleanup;
3595 }
3596 } else {
3597 hostlen = port - addrstr;
3598 port++;
3599 if (*port == '\0') {
3600 error_setg(errp, "vnc port cannot be empty");
3601 goto cleanup;
3602 }
3603 }
3604
bd269ebc
MA
3605 addr->type = SOCKET_ADDRESS_TYPE_INET;
3606 inet = &addr->u.inet;
275e0d61
DB
3607 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3608 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3609 } else {
3610 inet->host = g_strndup(addrstr, hostlen);
3611 }
3612 /* plain VNC port is just an offset, for websocket
3613 * port is absolute */
3614 if (websocket) {
3615 if (g_str_equal(addrstr, "") ||
3616 g_str_equal(addrstr, "on")) {
396f935a
DB
3617 if (displaynum == -1) {
3618 error_setg(errp, "explicit websocket port is required");
3619 goto cleanup;
3620 }
275e0d61
DB
3621 inet->port = g_strdup_printf(
3622 "%d", displaynum + 5700);
3623 if (to) {
3624 inet->has_to = true;
3625 inet->to = to + 5700;
3626 }
3627 } else {
3628 inet->port = g_strdup(port);
3629 }
3630 } else {
e5766eb4 3631 int offset = reverse ? 0 : 5900;
275e0d61
DB
3632 if (parse_uint_full(port, &baseport, 10) < 0) {
3633 error_setg(errp, "can't convert to a number: %s", port);
3634 goto cleanup;
3635 }
3636 if (baseport > 65535 ||
e5766eb4 3637 baseport + offset > 65535) {
275e0d61
DB
3638 error_setg(errp, "port %s out of range", port);
3639 goto cleanup;
3640 }
3641 inet->port = g_strdup_printf(
e5766eb4 3642 "%d", (int)baseport + offset);
275e0d61
DB
3643
3644 if (to) {
3645 inet->has_to = true;
e5766eb4 3646 inet->to = to + offset;
275e0d61
DB
3647 }
3648 }
3649
3650 inet->ipv4 = ipv4;
3651 inet->has_ipv4 = has_ipv4;
3652 inet->ipv6 = ipv6;
3653 inet->has_ipv6 = has_ipv6;
3654
3655 ret = baseport;
3656 }
3657
3658 *retaddr = addr;
3659
3660 cleanup:
3661 if (ret < 0) {
bd269ebc 3662 qapi_free_SocketAddress(addr);
275e0d61
DB
3663 }
3664 return ret;
3665}
3666
9f26f325
PMD
3667static void vnc_free_addresses(SocketAddress ***retsaddr,
3668 size_t *retnsaddr)
3669{
3670 size_t i;
3671
3672 for (i = 0; i < *retnsaddr; i++) {
3673 qapi_free_SocketAddress((*retsaddr)[i]);
3674 }
3675 g_free(*retsaddr);
3676
3677 *retsaddr = NULL;
3678 *retnsaddr = 0;
3679}
3680
275e0d61 3681static int vnc_display_get_addresses(QemuOpts *opts,
e5766eb4 3682 bool reverse,
bd269ebc 3683 SocketAddress ***retsaddr,
396f935a 3684 size_t *retnsaddr,
bd269ebc 3685 SocketAddress ***retwsaddr,
396f935a 3686 size_t *retnwsaddr,
275e0d61
DB
3687 Error **errp)
3688{
bd269ebc
MA
3689 SocketAddress *saddr = NULL;
3690 SocketAddress *wsaddr = NULL;
396f935a
DB
3691 QemuOptsIter addriter;
3692 const char *addr;
275e0d61
DB
3693 int to = qemu_opt_get_number(opts, "to", 0);
3694 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3695 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3696 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3697 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
396f935a
DB
3698 int displaynum = -1;
3699 int ret = -1;
275e0d61 3700
396f935a
DB
3701 *retsaddr = NULL;
3702 *retnsaddr = 0;
3703 *retwsaddr = NULL;
3704 *retnwsaddr = 0;
275e0d61 3705
396f935a
DB
3706 addr = qemu_opt_get(opts, "vnc");
3707 if (addr == NULL || g_str_equal(addr, "none")) {
3708 ret = 0;
3709 goto cleanup;
3710 }
3711 if (qemu_opt_get(opts, "websocket") &&
275e0d61
DB
3712 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3713 error_setg(errp,
3714 "SHA1 hash support is required for websockets");
396f935a
DB
3715 goto cleanup;
3716 }
3717
3718 qemu_opt_iter_init(&addriter, opts, "vnc");
3719 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3720 int rv;
e5766eb4 3721 rv = vnc_display_get_address(addr, false, reverse, 0, to,
396f935a
DB
3722 has_ipv4, has_ipv6,
3723 ipv4, ipv6,
3724 &saddr, errp);
3725 if (rv < 0) {
3726 goto cleanup;
3727 }
3728 /* Historical compat - first listen address can be used
3729 * to set the default websocket port
3730 */
3731 if (displaynum == -1) {
3732 displaynum = rv;
3733 }
bd269ebc 3734 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
396f935a 3735 (*retsaddr)[(*retnsaddr)++] = saddr;
275e0d61
DB
3736 }
3737
396f935a
DB
3738 /* If we had multiple primary displays, we don't do defaults
3739 * for websocket, and require explicit config instead. */
3740 if (*retnsaddr > 1) {
3741 displaynum = -1;
275e0d61 3742 }
396f935a
DB
3743
3744 qemu_opt_iter_init(&addriter, opts, "websocket");
3745 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
e5766eb4 3746 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
275e0d61
DB
3747 has_ipv4, has_ipv6,
3748 ipv4, ipv6,
3749 &wsaddr, errp) < 0) {
396f935a 3750 goto cleanup;
275e0d61 3751 }
396f935a
DB
3752
3753 /* Historical compat - if only a single listen address was
3754 * provided, then this is used to set the default listen
3755 * address for websocket too
3756 */
3757 if (*retnsaddr == 1 &&
bd269ebc
MA
3758 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3759 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3760 g_str_equal(wsaddr->u.inet.host, "") &&
3761 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3762 g_free(wsaddr->u.inet.host);
3763 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
275e0d61 3764 }
396f935a 3765
bd269ebc 3766 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
396f935a 3767 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
275e0d61 3768 }
275e0d61 3769
396f935a
DB
3770 ret = 0;
3771 cleanup:
3772 if (ret < 0) {
9f26f325
PMD
3773 vnc_free_addresses(retsaddr, retnsaddr);
3774 vnc_free_addresses(retwsaddr, retnwsaddr);
396f935a
DB
3775 }
3776 return ret;
275e0d61
DB
3777}
3778
8bd22f47 3779static int vnc_display_connect(VncDisplay *vd,
bd269ebc 3780 SocketAddress **saddr,
396f935a 3781 size_t nsaddr,
bd269ebc 3782 SocketAddress **wsaddr,
396f935a 3783 size_t nwsaddr,
8bd22f47
DB
3784 Error **errp)
3785{
3786 /* connect to viewer */
3787 QIOChannelSocket *sioc = NULL;
396f935a 3788 if (nwsaddr != 0) {
8bd22f47
DB
3789 error_setg(errp, "Cannot use websockets in reverse mode");
3790 return -1;
3791 }
396f935a
DB
3792 if (nsaddr != 1) {
3793 error_setg(errp, "Expected a single address in reverse mode");
3794 return -1;
3795 }
bd269ebc
MA
3796 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3797 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
8bd22f47
DB
3798 sioc = qio_channel_socket_new();
3799 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
396f935a 3800 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
8bd22f47
DB
3801 return -1;
3802 }
3803 vnc_connect(vd, sioc, false, false);
3804 object_unref(OBJECT(sioc));
3805 return 0;
3806}
3807
3808
3809static int vnc_display_listen_addr(VncDisplay *vd,
bd269ebc 3810 SocketAddress *addr,
8bd22f47
DB
3811 const char *name,
3812 QIOChannelSocket ***lsock,
3813 guint **lsock_tag,
3814 size_t *nlsock,
3815 Error **errp)
3816{
57a6d6d5 3817 QIODNSResolver *resolver = qio_dns_resolver_get_instance();
bd269ebc 3818 SocketAddress **rawaddrs = NULL;
57a6d6d5
DB
3819 size_t nrawaddrs = 0;
3820 Error *listenerr = NULL;
396f935a 3821 bool listening = false;
57a6d6d5 3822 size_t i;
8bd22f47 3823
57a6d6d5
DB
3824 if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs,
3825 &rawaddrs, errp) < 0) {
8bd22f47
DB
3826 return -1;
3827 }
3828
57a6d6d5
DB
3829 for (i = 0; i < nrawaddrs; i++) {
3830 QIOChannelSocket *sioc = qio_channel_socket_new();
3831
3832 qio_channel_set_name(QIO_CHANNEL(sioc), name);
3833 if (qio_channel_socket_listen_sync(
3834 sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {
7bc4f084 3835 object_unref(OBJECT(sioc));
57a6d6d5
DB
3836 continue;
3837 }
396f935a 3838 listening = true;
57a6d6d5
DB
3839 (*nlsock)++;
3840 *lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock);
3841 *lsock_tag = g_renew(guint, *lsock_tag, *nlsock);
3842
3843 (*lsock)[*nlsock - 1] = sioc;
3844 (*lsock_tag)[*nlsock - 1] = 0;
3845 }
3846
3847 for (i = 0; i < nrawaddrs; i++) {
bd269ebc 3848 qapi_free_SocketAddress(rawaddrs[i]);
57a6d6d5
DB
3849 }
3850 g_free(rawaddrs);
3851
3852 if (listenerr) {
396f935a 3853 if (!listening) {
57a6d6d5
DB
3854 error_propagate(errp, listenerr);
3855 return -1;
3856 } else {
3857 error_free(listenerr);
3858 }
3859 }
3860
3861 for (i = 0; i < *nlsock; i++) {
3862 (*lsock_tag)[i] = qio_channel_add_watch(
3863 QIO_CHANNEL((*lsock)[i]),
3864 G_IO_IN, vnc_listen_io, vd, NULL);
3865 }
8bd22f47
DB
3866
3867 return 0;
3868}
3869
3870
3871static int vnc_display_listen(VncDisplay *vd,
bd269ebc 3872 SocketAddress **saddr,
396f935a 3873 size_t nsaddr,
bd269ebc 3874 SocketAddress **wsaddr,
396f935a 3875 size_t nwsaddr,
8bd22f47
DB
3876 Error **errp)
3877{
396f935a 3878 size_t i;
8bd22f47 3879
396f935a
DB
3880 for (i = 0; i < nsaddr; i++) {
3881 if (vnc_display_listen_addr(vd, saddr[i],
3882 "vnc-listen",
3883 &vd->lsock,
3884 &vd->lsock_tag,
3885 &vd->nlsock,
3886 errp) < 0) {
3887 return -1;
3888 }
8bd22f47 3889 }
396f935a
DB
3890 for (i = 0; i < nwsaddr; i++) {
3891 if (vnc_display_listen_addr(vd, wsaddr[i],
3892 "vnc-ws-listen",
3893 &vd->lwebsock,
3894 &vd->lwebsock_tag,
3895 &vd->nlwebsock,
3896 errp) < 0) {
3897 return -1;
3898 }
8bd22f47
DB
3899 }
3900
3901 return 0;
3902}
3903
3904
4db14629 3905void vnc_display_open(const char *id, Error **errp)
71cab5ca 3906{
bf01c179 3907 VncDisplay *vd = vnc_display_find(id);
4db14629 3908 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
bd269ebc 3909 SocketAddress **saddr = NULL, **wsaddr = NULL;
396f935a 3910 size_t nsaddr, nwsaddr;
e2a11d9d 3911 const char *share, *device_id;
1d0d59fe 3912 QemuConsole *con;
a2c72de0
GA
3913 bool password = false;
3914 bool reverse = false;
3e305e4a 3915 const char *credid;
a2c72de0 3916 bool sasl = false;
d169f04b 3917#ifdef CONFIG_VNC_SASL
2f9606b3
AL
3918 int saslErr;
3919#endif
76655d6d 3920 int acl = 0;
3a0558b5 3921 int lock_key_sync = 1;
c5ce8333 3922 int key_delay_ms;
71cab5ca 3923
bf01c179 3924 if (!vd) {
2d55f0e8
PB
3925 error_setg(errp, "VNC display not active");
3926 return;
3927 }
bf01c179 3928 vnc_display_close(vd);
24236869 3929
4db14629
GH
3930 if (!opts) {
3931 return;
3932 }
274c3b52 3933
e5766eb4
GH
3934 reverse = qemu_opt_get_bool(opts, "reverse", false);
3935 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
396f935a 3936 &wsaddr, &nwsaddr, errp) < 0) {
e5560329 3937 goto fail;
e2a11d9d 3938 }
e5560329 3939
4db14629 3940 password = qemu_opt_get_bool(opts, "password", false);
800567a6
DB
3941 if (password) {
3942 if (fips_get_state()) {
3943 error_setg(errp,
3944 "VNC password auth disabled due to FIPS mode, "
3945 "consider using the VeNCrypt or SASL authentication "
3946 "methods as an alternative");
3947 goto fail;
3948 }
3949 if (!qcrypto_cipher_supports(
f844836d 3950 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
800567a6
DB
3951 error_setg(errp,
3952 "Cipher backend does not support DES RFB algorithm");
3953 goto fail;
3954 }
4db14629
GH
3955 }
3956
4db14629 3957 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
d3b0db6d 3958 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
4db14629 3959 sasl = qemu_opt_get_bool(opts, "sasl", false);
d169f04b
DB
3960#ifndef CONFIG_VNC_SASL
3961 if (sasl) {
3962 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3963 goto fail;
3964 }
3965#endif /* CONFIG_VNC_SASL */
3e305e4a
DB
3966 credid = qemu_opt_get(opts, "tls-creds");
3967 if (credid) {
3968 Object *creds;
3969 if (qemu_opt_get(opts, "tls") ||
3970 qemu_opt_get(opts, "x509") ||
3971 qemu_opt_get(opts, "x509verify")) {
3972 error_setg(errp,
c62e90af 3973 "'tls-creds' parameter is mutually exclusive with "
3e305e4a 3974 "'tls', 'x509' and 'x509verify' parameters");
4db14629
GH
3975 goto fail;
3976 }
3e305e4a
DB
3977
3978 creds = object_resolve_path_component(
3979 object_get_objects_root(), credid);
3980 if (!creds) {
3981 error_setg(errp, "No TLS credentials with id '%s'",
3982 credid);
3983 goto fail;
3984 }
bf01c179 3985 vd->tlscreds = (QCryptoTLSCreds *)
3e305e4a
DB
3986 object_dynamic_cast(creds,
3987 TYPE_QCRYPTO_TLS_CREDS);
bf01c179 3988 if (!vd->tlscreds) {
3e305e4a
DB
3989 error_setg(errp, "Object with id '%s' is not TLS credentials",
3990 credid);
3991 goto fail;
3992 }
bf01c179 3993 object_ref(OBJECT(vd->tlscreds));
3e305e4a 3994
bf01c179 3995 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3e305e4a
DB
3996 error_setg(errp,
3997 "Expecting TLS credentials with a server endpoint");
3998 goto fail;
3999 }
4000 } else {
4001 const char *path;
4002 bool tls = false, x509 = false, x509verify = false;
4003 tls = qemu_opt_get_bool(opts, "tls", false);
4004 if (tls) {
4005 path = qemu_opt_get(opts, "x509");
4006
4007 if (path) {
4008 x509 = true;
4009 } else {
4010 path = qemu_opt_get(opts, "x509verify");
4011 if (path) {
4012 x509 = true;
4013 x509verify = true;
4014 }
4015 }
bf01c179 4016 vd->tlscreds = vnc_display_create_creds(x509,
3e305e4a
DB
4017 x509verify,
4018 path,
bf01c179 4019 vd->id,
3e305e4a 4020 errp);
bf01c179 4021 if (!vd->tlscreds) {
3e305e4a
DB
4022 goto fail;
4023 }
4024 }
4db14629 4025 }
4db14629 4026 acl = qemu_opt_get_bool(opts, "acl", false);
4db14629
GH
4027
4028 share = qemu_opt_get(opts, "share");
4029 if (share) {
4030 if (strcmp(share, "ignore") == 0) {
bf01c179 4031 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
4db14629 4032 } else if (strcmp(share, "allow-exclusive") == 0) {
bf01c179 4033 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4db14629 4034 } else if (strcmp(share, "force-shared") == 0) {
bf01c179 4035 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
4db14629
GH
4036 } else {
4037 error_setg(errp, "unknown vnc share= option");
4038 goto fail;
4039 }
4040 } else {
bf01c179 4041 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4db14629 4042 }
bf01c179 4043 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4db14629 4044
4db14629 4045#ifdef CONFIG_VNC_JPEG
bf01c179 4046 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
4db14629 4047#endif
bf01c179 4048 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
e22492d3
PL
4049 /* adaptive updates are only used with tight encoding and
4050 * if lossy updates are enabled so we can disable all the
4051 * calculations otherwise */
bf01c179
DB
4052 if (!vd->lossy) {
4053 vd->non_adaptive = true;
e22492d3
PL
4054 }
4055
3e305e4a 4056 if (acl) {
bf01c179
DB
4057 if (strcmp(vd->id, "default") == 0) {
4058 vd->tlsaclname = g_strdup("vnc.x509dname");
c8496408 4059 } else {
bf01c179 4060 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
c8496408 4061 }
bf01c179 4062 qemu_acl_init(vd->tlsaclname);
2cc45228 4063 }
76655d6d
AL
4064#ifdef CONFIG_VNC_SASL
4065 if (acl && sasl) {
c8496408
GH
4066 char *aclname;
4067
bf01c179 4068 if (strcmp(vd->id, "default") == 0) {
c8496408
GH
4069 aclname = g_strdup("vnc.username");
4070 } else {
bf01c179 4071 aclname = g_strdup_printf("vnc.%s.username", vd->id);
c8496408 4072 }
bf01c179 4073 vd->sasl.acl = qemu_acl_init(aclname);
c8496408 4074 g_free(aclname);
76655d6d
AL
4075 }
4076#endif
4077
eda24e18
DB
4078 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
4079 vd->tlscreds, password,
4080 sasl, false, errp) < 0) {
4081 goto fail;
4082 }
7364dbda 4083 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
eda24e18
DB
4084
4085 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
4086 vd->tlscreds, password,
4087 sasl, true, errp) < 0) {
3e305e4a
DB
4088 goto fail;
4089 }
7364dbda 4090 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
24236869 4091
2f9606b3
AL
4092#ifdef CONFIG_VNC_SASL
4093 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2d55f0e8
PB
4094 error_setg(errp, "Failed to initialize SASL auth: %s",
4095 sasl_errstring(saslErr, NULL, NULL));
1ce52c78 4096 goto fail;
2f9606b3
AL
4097 }
4098#endif
bf01c179 4099 vd->lock_key_sync = lock_key_sync;
a54f0d2b
PO
4100 if (lock_key_sync) {
4101 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
4102 }
4103 vd->ledstate = 0;
bf01c179 4104 vd->key_delay_ms = key_delay_ms;
2f9606b3 4105
1d0d59fe
GH
4106 device_id = qemu_opt_get(opts, "display");
4107 if (device_id) {
1d0d59fe 4108 int head = qemu_opt_get_number(opts, "head", 0);
f2c1d54c 4109 Error *err = NULL;
1d0d59fe 4110
f2c1d54c
GH
4111 con = qemu_console_lookup_by_device_name(device_id, head, &err);
4112 if (err) {
4113 error_propagate(errp, err);
1d0d59fe
GH
4114 goto fail;
4115 }
4116 } else {
4117 con = NULL;
4118 }
4119
bf01c179
DB
4120 if (con != vd->dcl.con) {
4121 unregister_displaychangelistener(&vd->dcl);
4122 vd->dcl.con = con;
4123 register_displaychangelistener(&vd->dcl);
1d0d59fe
GH
4124 }
4125
fa03cb7f
MAL
4126 if (saddr == NULL) {
4127 goto cleanup;
4128 }
4129
3aa3eea3 4130 if (reverse) {
396f935a 4131 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
007fcd3e
PB
4132 goto fail;
4133 }
9712ecaf 4134 } else {
396f935a 4135 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
e0d03b8c
DB
4136 goto fail;
4137 }
24236869 4138 }
e0d03b8c 4139
275e0d61 4140 if (qemu_opt_get(opts, "to")) {
bf01c179 4141 vnc_display_print_local_addr(vd);
33df7bf3
PB
4142 }
4143
396f935a 4144 cleanup:
9f26f325
PMD
4145 vnc_free_addresses(&saddr, &nsaddr);
4146 vnc_free_addresses(&wsaddr, &nwsaddr);
2d55f0e8 4147 return;
1ce52c78
PB
4148
4149fail:
4ee74fa7 4150 vnc_display_close(vd);
396f935a 4151 goto cleanup;
24236869 4152}
13661089 4153
14f7143e 4154void vnc_display_add_client(const char *id, int csock, bool skipauth)
13661089 4155{
bf01c179 4156 VncDisplay *vd = vnc_display_find(id);
04d2529d 4157 QIOChannelSocket *sioc;
13661089 4158
bf01c179 4159 if (!vd) {
d616ccc5
GH
4160 return;
4161 }
04d2529d
DB
4162
4163 sioc = qio_channel_socket_new_fd(csock, NULL);
4164 if (sioc) {
10bcfe58 4165 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
bf01c179 4166 vnc_connect(vd, sioc, skipauth, false);
04d2529d
DB
4167 object_unref(OBJECT(sioc));
4168 }
13661089 4169}
4db14629 4170
9634f4e3 4171static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
2779672f
GA
4172{
4173 int i = 2;
4174 char *id;
4175
4176 id = g_strdup("default");
4177 while (qemu_opts_find(olist, id)) {
4178 g_free(id);
4179 id = g_strdup_printf("vnc%d", i++);
4180 }
4181 qemu_opts_set_id(opts, id);
4182}
4183
70b94331 4184QemuOpts *vnc_parse(const char *str, Error **errp)
4db14629 4185{
4db14629 4186 QemuOptsList *olist = qemu_find_opts("vnc");
70b94331 4187 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
81607cbf 4188 const char *id;
4db14629 4189
81607cbf
GA
4190 if (!opts) {
4191 return NULL;
4192 }
4193
4194 id = qemu_opts_id(opts);
4db14629
GH
4195 if (!id) {
4196 /* auto-assign id if not present */
2779672f 4197 vnc_auto_assign_id(olist, opts);
4db14629 4198 }
9634f4e3
GH
4199 return opts;
4200}
4201
28d0de7a 4202int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
9634f4e3
GH
4203{
4204 Error *local_err = NULL;
4205 char *id = (char *)qemu_opts_id(opts);
4db14629 4206
9634f4e3 4207 assert(id);
4db14629
GH
4208 vnc_display_init(id);
4209 vnc_display_open(id, &local_err);
4210 if (local_err != NULL) {
c29b77f9 4211 error_reportf_err(local_err, "Failed to start VNC server: ");
4db14629
GH
4212 exit(1);
4213 }
4214 return 0;
4215}
4216
4217static void vnc_register_config(void)
4218{
4219 qemu_add_opts(&qemu_vnc_opts);
4220}
34294e2f 4221opts_init(vnc_register_config);
This page took 1.759123 seconds and 4 git commands to generate.