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