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