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