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