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