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