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