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