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