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