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