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