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