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