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