]> Git Repo - qemu.git/blame - ui/vnc.c
ui/gtk: use GtkGlArea on wayland only
[qemu.git] / ui / vnc.c
CommitLineData
7d510b8c
FB
1/*
2 * QEMU VNC display driver
5fafdf24 3 *
7d510b8c
FB
4 * Copyright (C) 2006 Anthony Liguori <[email protected]>
5 * Copyright (C) 2006 Fabrice Bellard
19a490bf 6 * Copyright (C) 2009 Red Hat, Inc
5fafdf24 7 *
7d510b8c
FB
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
e16f4c87 27#include "qemu/osdep.h"
19a490bf 28#include "vnc.h"
bd023f95 29#include "vnc-jobs.h"
40066175 30#include "trace.h"
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"
eb815e24 38#include "qapi/qapi-events.h"
e688df6b 39#include "qapi/error.h"
9af23989 40#include "qapi/qapi-commands-ui.h"
8d447d10 41#include "ui/input.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) {
e2b72cb6 985 int bps;
e2b72cb6
DB
986 switch (vs->as.fmt) {
987 default:
988 case AUD_FMT_U8:
989 case AUD_FMT_S8:
990 bps = 1;
991 break;
992 case AUD_FMT_U16:
993 case AUD_FMT_S16:
994 bps = 2;
995 break;
996 case AUD_FMT_U32:
997 case AUD_FMT_S32:
998 bps = 4;
999 break;
1000 }
cf070658 1001 offset += vs->as.freq * bps * vs->as.nchannels;
e2b72cb6
DB
1002 }
1003
1004 /* Put a floor of 1MB on offset, so that if we have a large pending
1005 * buffer and the display is resized to a small size & back again
1006 * we don't suddenly apply a tiny send limit
1007 */
1008 offset = MAX(offset, 1024 * 1024);
1009
6aa22a29
DB
1010 if (vs->throttle_output_offset != offset) {
1011 trace_vnc_client_throttle_threshold(
1012 vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width,
1013 vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap);
1014 }
1015
e2b72cb6
DB
1016 vs->throttle_output_offset = offset;
1017}
1018
0bad8342
DB
1019static bool vnc_should_update(VncState *vs)
1020{
1021 switch (vs->update) {
1022 case VNC_STATE_UPDATE_NONE:
1023 break;
1024 case VNC_STATE_UPDATE_INCREMENTAL:
e2b72cb6 1025 /* Only allow incremental updates if the pending send queue
ada8d2e4
DB
1026 * is less than the permitted threshold, and the job worker
1027 * is completely idle.
0bad8342 1028 */
ada8d2e4
DB
1029 if (vs->output.offset < vs->throttle_output_offset &&
1030 vs->job_update == VNC_STATE_UPDATE_NONE) {
0bad8342
DB
1031 return true;
1032 }
6aa22a29
DB
1033 trace_vnc_client_throttle_incremental(
1034 vs, vs->ioc, vs->job_update, vs->output.offset);
0bad8342
DB
1035 break;
1036 case VNC_STATE_UPDATE_FORCE:
ada8d2e4
DB
1037 /* Only allow forced updates if the pending send queue
1038 * does not contain a previous forced update, and the
1039 * job worker is completely idle.
1040 *
1041 * Note this means we'll queue a forced update, even if
1042 * the output buffer size is otherwise over the throttle
1043 * output limit.
1044 */
1045 if (vs->force_update_offset == 0 &&
1046 vs->job_update == VNC_STATE_UPDATE_NONE) {
1047 return true;
1048 }
6aa22a29
DB
1049 trace_vnc_client_throttle_forced(
1050 vs, vs->ioc, vs->job_update, vs->force_update_offset);
ada8d2e4 1051 break;
0bad8342
DB
1052 }
1053 return false;
1054}
1055
6af998db 1056static int vnc_update_client(VncState *vs, int has_dirty)
24236869 1057{
b939eb89
DB
1058 VncDisplay *vd = vs->vd;
1059 VncJob *job;
1060 int y;
1061 int height, width;
1062 int n = 0;
1063
5a8be0f7
GH
1064 if (vs->disconnecting) {
1065 vnc_disconnect_finish(vs);
1066 return 0;
1067 }
1068
63658280 1069 vs->has_dirty += has_dirty;
0bad8342 1070 if (!vnc_should_update(vs)) {
b939eb89
DB
1071 return 0;
1072 }
1073
fef1bbad 1074 if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
b939eb89
DB
1075 return 0;
1076 }
1077
1078 /*
1079 * Send screen updates to the vnc client using the server
1080 * surface and server dirty map. guest surface updates
1081 * happening in parallel don't disturb us, the next pass will
1082 * send them to the client.
1083 */
1084 job = vnc_job_new(vs);
1085
1086 height = pixman_image_get_height(vd->server);
1087 width = pixman_image_get_width(vd->server);
1088
1089 y = 0;
1090 for (;;) {
1091 int x, h;
1092 unsigned long x2;
1093 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1094 height * VNC_DIRTY_BPL(vs),
1095 y * VNC_DIRTY_BPL(vs));
1096 if (offset == height * VNC_DIRTY_BPL(vs)) {
1097 /* no more dirty bits */
1098 break;
1099 }
1100 y = offset / VNC_DIRTY_BPL(vs);
1101 x = offset % VNC_DIRTY_BPL(vs);
1102 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1103 VNC_DIRTY_BPL(vs), x);
1104 bitmap_clear(vs->dirty[y], x, x2 - x);
1105 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1106 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1107 if (x2 > x) {
1108 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1109 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1110 }
1111 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1112 y += h;
1113 if (y == height) {
12b316d4 1114 break;
28a76be8
AL
1115 }
1116 }
24236869 1117 }
24236869 1118
ada8d2e4 1119 vs->job_update = vs->update;
728a7ac9 1120 vs->update = VNC_STATE_UPDATE_NONE;
ada8d2e4 1121 vnc_job_push(job);
b939eb89
DB
1122 vs->has_dirty = 0;
1123 return n;
24236869
FB
1124}
1125
429a8ed3 1126/* audio */
1127static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1128{
1129 VncState *vs = opaque;
1130
1131 switch (cmd) {
1132 case AUD_CNOTIFY_DISABLE:
bd023f95 1133 vnc_lock_output(vs);
46a183da
DB
1134 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1135 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1136 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
bd023f95 1137 vnc_unlock_output(vs);
429a8ed3 1138 vnc_flush(vs);
1139 break;
1140
1141 case AUD_CNOTIFY_ENABLE:
bd023f95 1142 vnc_lock_output(vs);
46a183da
DB
1143 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1144 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1145 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
bd023f95 1146 vnc_unlock_output(vs);
429a8ed3 1147 vnc_flush(vs);
1148 break;
1149 }
1150}
1151
1152static void audio_capture_destroy(void *opaque)
1153{
1154}
1155
1156static void audio_capture(void *opaque, void *buf, int size)
1157{
1158 VncState *vs = opaque;
1159
bd023f95 1160 vnc_lock_output(vs);
e2b72cb6
DB
1161 if (vs->output.offset < vs->throttle_output_offset) {
1162 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1163 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1164 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1165 vnc_write_u32(vs, size);
1166 vnc_write(vs, buf, size);
6aa22a29
DB
1167 } else {
1168 trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset);
e2b72cb6 1169 }
bd023f95 1170 vnc_unlock_output(vs);
429a8ed3 1171 vnc_flush(vs);
1172}
1173
1174static void audio_add(VncState *vs)
1175{
1176 struct audio_capture_ops ops;
1177
1178 if (vs->audio_cap) {
027a79c3 1179 error_report("audio already running");
429a8ed3 1180 return;
1181 }
1182
1183 ops.notify = audio_capture_notify;
1184 ops.destroy = audio_capture_destroy;
1185 ops.capture = audio_capture;
1186
1a7dafce 1187 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
429a8ed3 1188 if (!vs->audio_cap) {
027a79c3 1189 error_report("Failed to add audio capture");
429a8ed3 1190 }
1191}
1192
1193static void audio_del(VncState *vs)
1194{
1195 if (vs->audio_cap) {
1196 AUD_del_capture(vs->audio_cap, vs);
1197 vs->audio_cap = NULL;
1198 }
1199}
1200
198a0039
GH
1201static void vnc_disconnect_start(VncState *vs)
1202{
04d2529d 1203 if (vs->disconnecting) {
198a0039 1204 return;
04d2529d 1205 }
ad6374c4 1206 trace_vnc_client_disconnect_start(vs, vs->ioc);
8cf36489 1207 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
04d2529d
DB
1208 if (vs->ioc_tag) {
1209 g_source_remove(vs->ioc_tag);
a75d6f07 1210 vs->ioc_tag = 0;
04d2529d
DB
1211 }
1212 qio_channel_close(vs->ioc, NULL);
1213 vs->disconnecting = TRUE;
198a0039
GH
1214}
1215
7536ee4b 1216void vnc_disconnect_finish(VncState *vs)
198a0039 1217{
7d964c9d
CC
1218 int i;
1219
ad6374c4
DB
1220 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1221
bd023f95
CC
1222 vnc_jobs_join(vs); /* Wait encoding jobs */
1223
1224 vnc_lock_output(vs);
fb6ba0d5 1225 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
0d72f3d3 1226
5d418e3b
CC
1227 buffer_free(&vs->input);
1228 buffer_free(&vs->output);
4a80dba3 1229
fb6ba0d5 1230 qapi_free_VncClientInfo(vs->info);
4a80dba3 1231
161c4f20 1232 vnc_zlib_clear(vs);
380282b0 1233 vnc_tight_clear(vs);
148954fa 1234 vnc_zrle_clear(vs);
161c4f20 1235
198a0039
GH
1236#ifdef CONFIG_VNC_SASL
1237 vnc_sasl_client_cleanup(vs);
1238#endif /* CONFIG_VNC_SASL */
1239 audio_del(vs);
7bc9318b 1240 vnc_release_modifiers(vs);
198a0039 1241
90cd03a3 1242 if (vs->mouse_mode_notifier.notify != NULL) {
6fd8e79a 1243 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
90cd03a3
DB
1244 }
1245 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1246 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1247 /* last client gone */
1248 vnc_update_server_surface(vs->vd);
6fd8e79a 1249 }
41b4bef6 1250
bd023f95
CC
1251 vnc_unlock_output(vs);
1252
bd023f95 1253 qemu_mutex_destroy(&vs->output_mutex);
6fd8e79a
TH
1254 if (vs->bh != NULL) {
1255 qemu_bh_delete(vs->bh);
1256 }
175b2a6e 1257 buffer_free(&vs->jobs_buffer);
175b2a6e 1258
7d964c9d 1259 for (i = 0; i < VNC_STAT_ROWS; ++i) {
7267c094 1260 g_free(vs->lossy_rect[i]);
7d964c9d 1261 }
7267c094 1262 g_free(vs->lossy_rect);
04d2529d
DB
1263
1264 object_unref(OBJECT(vs->ioc));
1265 vs->ioc = NULL;
1266 object_unref(OBJECT(vs->sioc));
1267 vs->sioc = NULL;
7267c094 1268 g_free(vs);
198a0039 1269}
2f9606b3 1270
30b80fd5 1271size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
24236869 1272{
04d2529d
DB
1273 if (ret <= 0) {
1274 if (ret == 0) {
ad6374c4 1275 trace_vnc_client_eof(vs, vs->ioc);
537848ee 1276 vnc_disconnect_start(vs);
04d2529d 1277 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
ad6374c4
DB
1278 trace_vnc_client_io_error(vs, vs->ioc,
1279 errp ? error_get_pretty(*errp) :
1280 "Unknown");
537848ee 1281 vnc_disconnect_start(vs);
ea01e5fd 1282 }
24236869 1283
04d2529d
DB
1284 if (errp) {
1285 error_free(*errp);
1286 *errp = NULL;
1287 }
28a76be8 1288 return 0;
24236869
FB
1289 }
1290 return ret;
1291}
1292
5fb6c7a8
AL
1293
1294void vnc_client_error(VncState *vs)
24236869 1295{
198a0039
GH
1296 VNC_DEBUG("Closing down client sock: protocol error\n");
1297 vnc_disconnect_start(vs);
24236869
FB
1298}
1299
3e305e4a 1300
2f9606b3
AL
1301/*
1302 * Called to write a chunk of data to the client socket. The data may
1303 * be the raw data, or may have already been encoded by SASL.
1304 * The data will be written either straight onto the socket, or
1305 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1306 *
1307 * NB, it is theoretically possible to have 2 layers of encryption,
1308 * both SASL, and this TLS layer. It is highly unlikely in practice
1309 * though, since SASL encryption will typically be a no-op if TLS
1310 * is active
1311 *
1312 * Returns the number of bytes written, which may be less than
1313 * the requested 'datalen' if the socket would block. Returns
30b80fd5 1314 * 0 on I/O error, and disconnects the client socket.
2f9606b3 1315 */
30b80fd5 1316size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
24236869 1317{
04d2529d 1318 Error *err = NULL;
fdd1ab6a 1319 ssize_t ret;
2cc45228
DB
1320 ret = qio_channel_write(
1321 vs->ioc, (const char *)data, datalen, &err);
23decc87 1322 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
04d2529d 1323 return vnc_client_io_error(vs, ret, &err);
2f9606b3
AL
1324}
1325
1326
1327/*
1328 * Called to write buffered data to the client socket, when not
1329 * using any SASL SSF encryption layers. Will write as much data
1330 * as possible without blocking. If all buffered data is written,
1331 * will switch the FD poll() handler back to read monitoring.
1332 *
1333 * Returns the number of bytes written, which may be less than
30b80fd5
DB
1334 * the buffered output data if the socket would block. Returns
1335 * 0 on I/O error, and disconnects the client socket.
2f9606b3 1336 */
30b80fd5 1337static size_t vnc_client_write_plain(VncState *vs)
2f9606b3 1338{
6aa22a29 1339 size_t offset;
30b80fd5 1340 size_t ret;
2f9606b3
AL
1341
1342#ifdef CONFIG_VNC_SASL
23decc87 1343 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
2f9606b3
AL
1344 vs->output.buffer, vs->output.capacity, vs->output.offset,
1345 vs->sasl.waitWriteSSF);
1346
1347 if (vs->sasl.conn &&
1348 vs->sasl.runSSF &&
1349 vs->sasl.waitWriteSSF) {
1350 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1351 if (ret)
1352 vs->sasl.waitWriteSSF -= ret;
1353 } else
1354#endif /* CONFIG_VNC_SASL */
1355 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
24236869 1356 if (!ret)
2f9606b3 1357 return 0;
24236869 1358
ada8d2e4 1359 if (ret >= vs->force_update_offset) {
6aa22a29
DB
1360 if (vs->force_update_offset != 0) {
1361 trace_vnc_client_unthrottle_forced(vs, vs->ioc);
1362 }
ada8d2e4
DB
1363 vs->force_update_offset = 0;
1364 } else {
1365 vs->force_update_offset -= ret;
1366 }
6aa22a29 1367 offset = vs->output.offset;
32ed2680 1368 buffer_advance(&vs->output, ret);
6aa22a29
DB
1369 if (offset >= vs->throttle_output_offset &&
1370 vs->output.offset < vs->throttle_output_offset) {
1371 trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset);
1372 }
24236869
FB
1373
1374 if (vs->output.offset == 0) {
04d2529d
DB
1375 if (vs->ioc_tag) {
1376 g_source_remove(vs->ioc_tag);
1377 }
1378 vs->ioc_tag = qio_channel_add_watch(
1379 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
24236869 1380 }
2f9606b3
AL
1381
1382 return ret;
1383}
1384
1385
1386/*
1387 * First function called whenever there is data to be written to
1388 * the client socket. Will delegate actual work according to whether
1389 * SASL SSF layers are enabled (thus requiring encryption calls)
1390 */
04d2529d 1391static void vnc_client_write_locked(VncState *vs)
2f9606b3 1392{
2f9606b3
AL
1393#ifdef CONFIG_VNC_SASL
1394 if (vs->sasl.conn &&
1395 vs->sasl.runSSF &&
9678d950
BS
1396 !vs->sasl.waitWriteSSF) {
1397 vnc_client_write_sasl(vs);
1398 } else
2f9606b3 1399#endif /* CONFIG_VNC_SASL */
7536ee4b 1400 {
d5f04223 1401 vnc_client_write_plain(vs);
7536ee4b 1402 }
24236869
FB
1403}
1404
04d2529d 1405static void vnc_client_write(VncState *vs)
bd023f95 1406{
bd023f95
CC
1407
1408 vnc_lock_output(vs);
d5f04223 1409 if (vs->output.offset) {
04d2529d
DB
1410 vnc_client_write_locked(vs);
1411 } else if (vs->ioc != NULL) {
1412 if (vs->ioc_tag) {
1413 g_source_remove(vs->ioc_tag);
1414 }
1415 vs->ioc_tag = qio_channel_add_watch(
1416 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
bd023f95
CC
1417 }
1418 vnc_unlock_output(vs);
1419}
1420
5fb6c7a8 1421void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
24236869
FB
1422{
1423 vs->read_handler = func;
1424 vs->read_handler_expect = expecting;
1425}
1426
2f9606b3
AL
1427
1428/*
1429 * Called to read a chunk of data from the client socket. The data may
1430 * be the raw data, or may need to be further decoded by SASL.
1431 * The data will be read either straight from to the socket, or
1432 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1433 *
1434 * NB, it is theoretically possible to have 2 layers of encryption,
1435 * both SASL, and this TLS layer. It is highly unlikely in practice
1436 * though, since SASL encryption will typically be a no-op if TLS
1437 * is active
1438 *
1439 * Returns the number of bytes read, which may be less than
1440 * the requested 'datalen' if the socket would block. Returns
30b80fd5 1441 * 0 on I/O error or EOF, and disconnects the client socket.
2f9606b3 1442 */
30b80fd5 1443size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
24236869 1444{
fdd1ab6a 1445 ssize_t ret;
04d2529d 1446 Error *err = NULL;
2cc45228
DB
1447 ret = qio_channel_read(
1448 vs->ioc, (char *)data, datalen, &err);
23decc87 1449 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
04d2529d 1450 return vnc_client_io_error(vs, ret, &err);
2f9606b3 1451}
24236869 1452
2f9606b3
AL
1453
1454/*
1455 * Called to read data from the client socket to the input buffer,
1456 * when not using any SASL SSF encryption layers. Will read as much
1457 * data as possible without blocking.
1458 *
30b80fd5
DB
1459 * Returns the number of bytes read, which may be less than
1460 * the requested 'datalen' if the socket would block. Returns
1461 * 0 on I/O error or EOF, and disconnects the client socket.
2f9606b3 1462 */
30b80fd5 1463static size_t vnc_client_read_plain(VncState *vs)
2f9606b3 1464{
30b80fd5 1465 size_t ret;
23decc87 1466 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
2f9606b3
AL
1467 vs->input.buffer, vs->input.capacity, vs->input.offset);
1468 buffer_reserve(&vs->input, 4096);
1469 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1470 if (!ret)
1471 return 0;
24236869 1472 vs->input.offset += ret;
2f9606b3
AL
1473 return ret;
1474}
1475
175b2a6e
CC
1476static void vnc_jobs_bh(void *opaque)
1477{
1478 VncState *vs = opaque;
1479
1480 vnc_jobs_consume_buffer(vs);
1481}
2f9606b3
AL
1482
1483/*
1484 * First function called whenever there is more data to be read from
1485 * the client socket. Will delegate actual work according to whether
1486 * SASL SSF layers are enabled (thus requiring decryption calls)
ea697449 1487 * Returns 0 on success, -1 if client disconnected
2f9606b3 1488 */
ea697449 1489static int vnc_client_read(VncState *vs)
2f9606b3 1490{
30b80fd5 1491 size_t ret;
2f9606b3
AL
1492
1493#ifdef CONFIG_VNC_SASL
1494 if (vs->sasl.conn && vs->sasl.runSSF)
1495 ret = vnc_client_read_sasl(vs);
1496 else
1497#endif /* CONFIG_VNC_SASL */
d5f04223 1498 ret = vnc_client_read_plain(vs);
198a0039 1499 if (!ret) {
04d2529d 1500 if (vs->disconnecting) {
198a0039 1501 vnc_disconnect_finish(vs);
ea697449 1502 return -1;
04d2529d 1503 }
ea697449 1504 return 0;
198a0039 1505 }
24236869
FB
1506
1507 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
28a76be8
AL
1508 size_t len = vs->read_handler_expect;
1509 int ret;
1510
1511 ret = vs->read_handler(vs, vs->input.buffer, len);
04d2529d 1512 if (vs->disconnecting) {
198a0039 1513 vnc_disconnect_finish(vs);
ea697449 1514 return -1;
198a0039 1515 }
28a76be8
AL
1516
1517 if (!ret) {
32ed2680 1518 buffer_advance(&vs->input, len);
28a76be8
AL
1519 } else {
1520 vs->read_handler_expect = ret;
1521 }
24236869 1522 }
ea697449 1523 return 0;
24236869
FB
1524}
1525
04d2529d
DB
1526gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1527 GIOCondition condition, void *opaque)
1528{
1529 VncState *vs = opaque;
1530 if (condition & G_IO_IN) {
ea697449 1531 if (vnc_client_read(vs) < 0) {
d49b87f0 1532 goto end;
ea697449 1533 }
04d2529d
DB
1534 }
1535 if (condition & G_IO_OUT) {
1536 vnc_client_write(vs);
1537 }
d49b87f0
KK
1538end:
1539 if (vs->disconnecting) {
1540 if (vs->ioc_tag != 0) {
1541 g_source_remove(vs->ioc_tag);
1542 }
1543 vs->ioc_tag = 0;
1544 }
04d2529d
DB
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 &&
dffa1de0
DB
1575 (vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) >
1576 vs->throttle_output_offset) {
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 }
d49b87f0
KK
1633 if (vs->disconnecting) {
1634 if (vs->ioc_tag != 0) {
1635 g_source_remove(vs->ioc_tag);
1636 }
1637 vs->ioc_tag = 0;
1638 }
bd023f95 1639 vnc_unlock_output(vs);
24236869
FB
1640}
1641
71a8cdec 1642static uint8_t read_u8(uint8_t *data, size_t offset)
24236869
FB
1643{
1644 return data[offset];
1645}
1646
71a8cdec 1647static uint16_t read_u16(uint8_t *data, size_t offset)
24236869
FB
1648{
1649 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1650}
1651
71a8cdec 1652static int32_t read_s32(uint8_t *data, size_t offset)
24236869
FB
1653{
1654 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1655 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1656}
1657
5fb6c7a8 1658uint32_t read_u32(uint8_t *data, size_t offset)
24236869
FB
1659{
1660 return ((data[offset] << 24) | (data[offset + 1] << 16) |
28a76be8 1661 (data[offset + 2] << 8) | data[offset + 3]);
24236869
FB
1662}
1663
60fe76f3 1664static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
24236869
FB
1665{
1666}
1667
9e8dd451 1668static void check_pointer_type_change(Notifier *notifier, void *data)
564c337e 1669{
37c34d9d 1670 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
14768eba 1671 int absolute = qemu_input_is_absolute();
37c34d9d 1672
29fa4ed9 1673 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
bd023f95 1674 vnc_lock_output(vs);
46a183da 1675 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
28a76be8
AL
1676 vnc_write_u8(vs, 0);
1677 vnc_write_u16(vs, 1);
1678 vnc_framebuffer_update(vs, absolute, 0,
bea60dd7
PL
1679 pixman_image_get_width(vs->vd->server),
1680 pixman_image_get_height(vs->vd->server),
29fa4ed9 1681 VNC_ENCODING_POINTER_TYPE_CHANGE);
bd023f95 1682 vnc_unlock_output(vs);
28a76be8 1683 vnc_flush(vs);
564c337e
FB
1684 }
1685 vs->absolute = absolute;
1686}
1687
24236869
FB
1688static void pointer_event(VncState *vs, int button_mask, int x, int y)
1689{
7fb1cf16 1690 static uint32_t bmap[INPUT_BUTTON__MAX] = {
14768eba
GH
1691 [INPUT_BUTTON_LEFT] = 0x01,
1692 [INPUT_BUTTON_MIDDLE] = 0x02,
1693 [INPUT_BUTTON_RIGHT] = 0x04,
f22d0af0
GH
1694 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1695 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
14768eba
GH
1696 };
1697 QemuConsole *con = vs->vd->dcl.con;
bea60dd7
PL
1698 int width = pixman_image_get_width(vs->vd->server);
1699 int height = pixman_image_get_height(vs->vd->server);
24236869 1700
14768eba
GH
1701 if (vs->last_bmask != button_mask) {
1702 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1703 vs->last_bmask = button_mask;
1704 }
564c337e
FB
1705
1706 if (vs->absolute) {
9cfa7ab9
PV
1707 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1708 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
29fa4ed9 1709 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
14768eba
GH
1710 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1711 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
564c337e 1712 } else {
14768eba
GH
1713 if (vs->last_x != -1) {
1714 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1715 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1716 }
28a76be8
AL
1717 vs->last_x = x;
1718 vs->last_y = y;
24236869 1719 }
14768eba 1720 qemu_input_event_sync();
24236869
FB
1721}
1722
64f5a135
FB
1723static void reset_keys(VncState *vs)
1724{
1725 int i;
1726 for(i = 0; i < 256; i++) {
1727 if (vs->modifiers_state[i]) {
8d447d10 1728 qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
c5ce8333 1729 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
64f5a135
FB
1730 vs->modifiers_state[i] = 0;
1731 }
1732 }
1733}
1734
a528b80c
AZ
1735static void press_key(VncState *vs, int keysym)
1736{
abb4f2c9
GH
1737 int keycode = keysym2scancode(vs->vd->kbd_layout, keysym,
1738 false, false, false) & SCANCODE_KEYMASK;
8d447d10 1739 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
c5ce8333 1740 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
8d447d10 1741 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
c5ce8333 1742 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
a528b80c
AZ
1743}
1744
ab99e5c1
LL
1745static void vnc_led_state_change(VncState *vs)
1746{
ab99e5c1
LL
1747 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1748 return;
1749 }
1750
ab99e5c1
LL
1751 vnc_lock_output(vs);
1752 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1753 vnc_write_u8(vs, 0);
1754 vnc_write_u16(vs, 1);
1755 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
a54f0d2b 1756 vnc_write_u8(vs, vs->vd->ledstate);
ab99e5c1
LL
1757 vnc_unlock_output(vs);
1758 vnc_flush(vs);
1759}
1760
7ffb82ca
GH
1761static void kbd_leds(void *opaque, int ledstate)
1762{
a54f0d2b
PO
1763 VncDisplay *vd = opaque;
1764 VncState *client;
7ffb82ca 1765
40066175
GH
1766 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1767 (ledstate & QEMU_NUM_LOCK_LED),
1768 (ledstate & QEMU_SCROLL_LOCK_LED));
1769
a54f0d2b
PO
1770 if (ledstate == vd->ledstate) {
1771 return;
96f3d174 1772 }
ab99e5c1 1773
a54f0d2b
PO
1774 vd->ledstate = ledstate;
1775
1776 QTAILQ_FOREACH(client, &vd->clients, next) {
1777 vnc_led_state_change(client);
ab99e5c1 1778 }
7ffb82ca
GH
1779}
1780
9ca313aa 1781static void do_key_event(VncState *vs, int down, int keycode, int sym)
24236869 1782{
64f5a135
FB
1783 /* QEMU console switch */
1784 switch(keycode) {
1785 case 0x2a: /* Left Shift */
1786 case 0x36: /* Right Shift */
1787 case 0x1d: /* Left CTRL */
1788 case 0x9d: /* Right CTRL */
1789 case 0x38: /* Left ALT */
1790 case 0xb8: /* Right ALT */
1791 if (down)
1792 vs->modifiers_state[keycode] = 1;
1793 else
1794 vs->modifiers_state[keycode] = 0;
1795 break;
5fafdf24 1796 case 0x02 ... 0x0a: /* '1' to '9' keys */
1d0d59fe
GH
1797 if (vs->vd->dcl.con == NULL &&
1798 down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
64f5a135
FB
1799 /* Reset the modifiers sent to the current console */
1800 reset_keys(vs);
1801 console_select(keycode - 0x02);
1802 return;
1803 }
1804 break;
28a76be8
AL
1805 case 0x3a: /* CapsLock */
1806 case 0x45: /* NumLock */
7ffb82ca 1807 if (down)
a528b80c
AZ
1808 vs->modifiers_state[keycode] ^= 1;
1809 break;
1810 }
1811
e7b2aacc
LL
1812 /* Turn off the lock state sync logic if the client support the led
1813 state extension.
1814 */
9892088b 1815 if (down && vs->vd->lock_key_sync &&
e7b2aacc 1816 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
3a0558b5 1817 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
a528b80c
AZ
1818 /* If the numlock state needs to change then simulate an additional
1819 keypress before sending this one. This will happen if the user
1820 toggles numlock away from the VNC window.
1821 */
753b4053 1822 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
a528b80c 1823 if (!vs->modifiers_state[0x45]) {
40066175 1824 trace_vnc_key_sync_numlock(true);
a528b80c
AZ
1825 vs->modifiers_state[0x45] = 1;
1826 press_key(vs, 0xff7f);
1827 }
1828 } else {
1829 if (vs->modifiers_state[0x45]) {
40066175 1830 trace_vnc_key_sync_numlock(false);
a528b80c
AZ
1831 vs->modifiers_state[0x45] = 0;
1832 press_key(vs, 0xff7f);
1833 }
1834 }
64f5a135 1835 }
24236869 1836
9892088b 1837 if (down && vs->vd->lock_key_sync &&
e7b2aacc 1838 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
3a0558b5 1839 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
6b132502
GH
1840 /* If the capslock state needs to change then simulate an additional
1841 keypress before sending this one. This will happen if the user
1842 toggles capslock away from the VNC window.
1843 */
1844 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1845 int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
1846 int capslock = !!(vs->modifiers_state[0x3a]);
1847 if (capslock) {
1848 if (uppercase == shift) {
40066175 1849 trace_vnc_key_sync_capslock(false);
6b132502
GH
1850 vs->modifiers_state[0x3a] = 0;
1851 press_key(vs, 0xffe5);
1852 }
1853 } else {
1854 if (uppercase != shift) {
40066175 1855 trace_vnc_key_sync_capslock(true);
6b132502
GH
1856 vs->modifiers_state[0x3a] = 1;
1857 press_key(vs, 0xffe5);
1858 }
1859 }
1860 }
1861
81c0d5a6 1862 if (qemu_console_is_graphic(NULL)) {
8d447d10 1863 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
c5ce8333 1864 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
64f5a135 1865 } else {
e26437c2
GH
1866 bool numlock = vs->modifiers_state[0x45];
1867 bool control = (vs->modifiers_state[0x1d] ||
1868 vs->modifiers_state[0x9d]);
64f5a135
FB
1869 /* QEMU console emulation */
1870 if (down) {
1871 switch (keycode) {
1872 case 0x2a: /* Left Shift */
1873 case 0x36: /* Right Shift */
1874 case 0x1d: /* Left CTRL */
1875 case 0x9d: /* Right CTRL */
1876 case 0x38: /* Left ALT */
1877 case 0xb8: /* Right ALT */
1878 break;
1879 case 0xc8:
1880 kbd_put_keysym(QEMU_KEY_UP);
1881 break;
1882 case 0xd0:
1883 kbd_put_keysym(QEMU_KEY_DOWN);
1884 break;
1885 case 0xcb:
1886 kbd_put_keysym(QEMU_KEY_LEFT);
1887 break;
1888 case 0xcd:
1889 kbd_put_keysym(QEMU_KEY_RIGHT);
1890 break;
1891 case 0xd3:
1892 kbd_put_keysym(QEMU_KEY_DELETE);
1893 break;
1894 case 0xc7:
1895 kbd_put_keysym(QEMU_KEY_HOME);
1896 break;
1897 case 0xcf:
1898 kbd_put_keysym(QEMU_KEY_END);
1899 break;
1900 case 0xc9:
1901 kbd_put_keysym(QEMU_KEY_PAGEUP);
1902 break;
1903 case 0xd1:
1904 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1905 break;
bb0a18e1
GH
1906
1907 case 0x47:
1908 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1909 break;
1910 case 0x48:
1911 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1912 break;
1913 case 0x49:
1914 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1915 break;
1916 case 0x4b:
1917 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1918 break;
1919 case 0x4c:
1920 kbd_put_keysym('5');
1921 break;
1922 case 0x4d:
1923 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1924 break;
1925 case 0x4f:
1926 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1927 break;
1928 case 0x50:
1929 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1930 break;
1931 case 0x51:
1932 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1933 break;
1934 case 0x52:
1935 kbd_put_keysym('0');
1936 break;
1937 case 0x53:
1938 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1939 break;
1940
1941 case 0xb5:
1942 kbd_put_keysym('/');
1943 break;
1944 case 0x37:
1945 kbd_put_keysym('*');
1946 break;
1947 case 0x4a:
1948 kbd_put_keysym('-');
1949 break;
1950 case 0x4e:
1951 kbd_put_keysym('+');
1952 break;
1953 case 0x9c:
1954 kbd_put_keysym('\n');
1955 break;
1956
64f5a135 1957 default:
e26437c2
GH
1958 if (control) {
1959 kbd_put_keysym(sym & 0x1f);
1960 } else {
1961 kbd_put_keysym(sym);
1962 }
64f5a135
FB
1963 break;
1964 }
1965 }
1966 }
24236869
FB
1967}
1968
7bc9318b
GH
1969static void vnc_release_modifiers(VncState *vs)
1970{
1971 static const int keycodes[] = {
1972 /* shift, control, alt keys, both left & right */
1973 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
1974 };
1975 int i, keycode;
1976
81c0d5a6 1977 if (!qemu_console_is_graphic(NULL)) {
7bc9318b
GH
1978 return;
1979 }
1980 for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
1981 keycode = keycodes[i];
1982 if (!vs->modifiers_state[keycode]) {
1983 continue;
1984 }
8d447d10 1985 qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
c5ce8333 1986 qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
7bc9318b
GH
1987 }
1988}
1989
40066175
GH
1990static const char *code2name(int keycode)
1991{
977c736f 1992 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
40066175
GH
1993}
1994
bdbd7676
FB
1995static void key_event(VncState *vs, int down, uint32_t sym)
1996{
abb4f2c9
GH
1997 bool shift = vs->modifiers_state[0x2a] || vs->modifiers_state[0x36];
1998 bool altgr = vs->modifiers_state[0xb8];
1999 bool ctrl = vs->modifiers_state[0x1d] || vs->modifiers_state[0x9d];
9ca313aa 2000 int keycode;
4a93fe17 2001 int lsym = sym;
9ca313aa 2002
81c0d5a6 2003 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
4a93fe17
GH
2004 lsym = lsym - 'A' + 'a';
2005 }
9ca313aa 2006
abb4f2c9
GH
2007 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
2008 shift, altgr, ctrl) & SCANCODE_KEYMASK;
40066175 2009 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
9ca313aa
AL
2010 do_key_event(vs, down, keycode, sym);
2011}
2012
2013static void ext_key_event(VncState *vs, int down,
2014 uint32_t sym, uint16_t keycode)
2015{
2016 /* if the user specifies a keyboard layout, always use it */
40066175 2017 if (keyboard_layout) {
9ca313aa 2018 key_event(vs, down, sym);
40066175
GH
2019 } else {
2020 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
9ca313aa 2021 do_key_event(vs, down, keycode, sym);
40066175 2022 }
bdbd7676
FB
2023}
2024
24236869 2025static void framebuffer_update_request(VncState *vs, int incremental,
bea60dd7 2026 int x, int y, int w, int h)
24236869 2027{
bea60dd7 2028 if (incremental) {
fef1bbad
DB
2029 if (vs->update != VNC_STATE_UPDATE_FORCE) {
2030 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
2031 }
2032 } else {
2033 vs->update = VNC_STATE_UPDATE_FORCE;
2034 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
24236869
FB
2035 }
2036}
2037
9ca313aa
AL
2038static void send_ext_key_event_ack(VncState *vs)
2039{
bd023f95 2040 vnc_lock_output(vs);
46a183da 2041 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
9ca313aa
AL
2042 vnc_write_u8(vs, 0);
2043 vnc_write_u16(vs, 1);
d39fa6d8 2044 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2045 pixman_image_get_width(vs->vd->server),
2046 pixman_image_get_height(vs->vd->server),
29fa4ed9 2047 VNC_ENCODING_EXT_KEY_EVENT);
bd023f95 2048 vnc_unlock_output(vs);
9ca313aa
AL
2049 vnc_flush(vs);
2050}
2051
429a8ed3 2052static void send_ext_audio_ack(VncState *vs)
2053{
bd023f95 2054 vnc_lock_output(vs);
46a183da 2055 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
429a8ed3 2056 vnc_write_u8(vs, 0);
2057 vnc_write_u16(vs, 1);
d39fa6d8 2058 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2059 pixman_image_get_width(vs->vd->server),
2060 pixman_image_get_height(vs->vd->server),
29fa4ed9 2061 VNC_ENCODING_AUDIO);
bd023f95 2062 vnc_unlock_output(vs);
429a8ed3 2063 vnc_flush(vs);
2064}
2065
24236869
FB
2066static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2067{
2068 int i;
29fa4ed9 2069 unsigned int enc = 0;
24236869 2070
29fa4ed9 2071 vs->features = 0;
a9f20d31 2072 vs->vnc_encoding = 0;
d1af0e05
CC
2073 vs->tight.compression = 9;
2074 vs->tight.quality = -1; /* Lossless by default */
564c337e 2075 vs->absolute = -1;
24236869 2076
8a0f0d0c
CC
2077 /*
2078 * Start from the end because the encodings are sent in order of preference.
e5bed759 2079 * This way the preferred encoding (first encoding defined in the array)
8a0f0d0c
CC
2080 * will be set at the end of the loop.
2081 */
24236869 2082 for (i = n_encodings - 1; i >= 0; i--) {
29fa4ed9
AL
2083 enc = encodings[i];
2084 switch (enc) {
2085 case VNC_ENCODING_RAW:
a9f20d31 2086 vs->vnc_encoding = enc;
29fa4ed9
AL
2087 break;
2088 case VNC_ENCODING_COPYRECT:
753b4053 2089 vs->features |= VNC_FEATURE_COPYRECT_MASK;
29fa4ed9
AL
2090 break;
2091 case VNC_ENCODING_HEXTILE:
2092 vs->features |= VNC_FEATURE_HEXTILE_MASK;
a9f20d31 2093 vs->vnc_encoding = enc;
29fa4ed9 2094 break;
380282b0
CC
2095 case VNC_ENCODING_TIGHT:
2096 vs->features |= VNC_FEATURE_TIGHT_MASK;
2097 vs->vnc_encoding = enc;
2098 break;
fe3e7f2d 2099#ifdef CONFIG_VNC_PNG
efe556ad
CC
2100 case VNC_ENCODING_TIGHT_PNG:
2101 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2102 vs->vnc_encoding = enc;
2103 break;
fe3e7f2d 2104#endif
059cef40
AL
2105 case VNC_ENCODING_ZLIB:
2106 vs->features |= VNC_FEATURE_ZLIB_MASK;
a9f20d31 2107 vs->vnc_encoding = enc;
059cef40 2108 break;
148954fa
CC
2109 case VNC_ENCODING_ZRLE:
2110 vs->features |= VNC_FEATURE_ZRLE_MASK;
2111 vs->vnc_encoding = enc;
2112 break;
2113 case VNC_ENCODING_ZYWRLE:
2114 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2115 vs->vnc_encoding = enc;
2116 break;
29fa4ed9
AL
2117 case VNC_ENCODING_DESKTOPRESIZE:
2118 vs->features |= VNC_FEATURE_RESIZE_MASK;
2119 break;
2120 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2121 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2122 break;
d467b679
GH
2123 case VNC_ENCODING_RICH_CURSOR:
2124 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
91ec41dc
FZ
2125 if (vs->vd->cursor) {
2126 vnc_cursor_define(vs);
2127 }
d467b679 2128 break;
29fa4ed9 2129 case VNC_ENCODING_EXT_KEY_EVENT:
9ca313aa
AL
2130 send_ext_key_event_ack(vs);
2131 break;
29fa4ed9 2132 case VNC_ENCODING_AUDIO:
429a8ed3 2133 send_ext_audio_ack(vs);
2134 break;
29fa4ed9
AL
2135 case VNC_ENCODING_WMVi:
2136 vs->features |= VNC_FEATURE_WMVI_MASK;
ca4cca4d 2137 break;
ab99e5c1
LL
2138 case VNC_ENCODING_LED_STATE:
2139 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2140 break;
fb437313 2141 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
d1af0e05 2142 vs->tight.compression = (enc & 0x0F);
fb437313
AL
2143 break;
2144 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
b31f519e
CC
2145 if (vs->vd->lossy) {
2146 vs->tight.quality = (enc & 0x0F);
2147 }
fb437313 2148 break;
29fa4ed9
AL
2149 default:
2150 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2151 break;
2152 }
24236869 2153 }
6356e472 2154 vnc_desktop_resize(vs);
9e8dd451 2155 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
ab99e5c1 2156 vnc_led_state_change(vs);
24236869
FB
2157}
2158
6cec5487
AL
2159static void set_pixel_conversion(VncState *vs)
2160{
9f64916d
GH
2161 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2162
2163 if (fmt == VNC_SERVER_FB_FORMAT) {
6cec5487 2164 vs->write_pixels = vnc_write_pixels_copy;
70a4568f 2165 vnc_hextile_set_pixel_conversion(vs, 0);
6cec5487
AL
2166 } else {
2167 vs->write_pixels = vnc_write_pixels_generic;
70a4568f 2168 vnc_hextile_set_pixel_conversion(vs, 1);
6cec5487
AL
2169 }
2170}
2171
0c426e45
AG
2172static void send_color_map(VncState *vs)
2173{
2174 int i;
2175
2176 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2177 vnc_write_u8(vs, 0); /* padding */
2178 vnc_write_u16(vs, 0); /* first color */
2179 vnc_write_u16(vs, 256); /* # of colors */
2180
2181 for (i = 0; i < 256; i++) {
2182 PixelFormat *pf = &vs->client_pf;
2183
2184 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2185 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2186 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2187 }
2188}
2189
ec9fb41a 2190static void set_pixel_format(VncState *vs, int bits_per_pixel,
28a76be8
AL
2191 int big_endian_flag, int true_color_flag,
2192 int red_max, int green_max, int blue_max,
2193 int red_shift, int green_shift, int blue_shift)
24236869 2194{
3512779a 2195 if (!true_color_flag) {
0c426e45
AG
2196 /* Expose a reasonable default 256 color map */
2197 bits_per_pixel = 8;
0c426e45
AG
2198 red_max = 7;
2199 green_max = 7;
2200 blue_max = 3;
2201 red_shift = 0;
2202 green_shift = 3;
2203 blue_shift = 6;
3512779a 2204 }
24236869 2205
e6908bfe
PM
2206 switch (bits_per_pixel) {
2207 case 8:
2208 case 16:
2209 case 32:
2210 break;
2211 default:
2212 vnc_client_error(vs);
2213 return;
2214 }
2215
4c65fed8 2216 vs->client_pf.rmax = red_max ? red_max : 0xFF;
7c9209e7 2217 vs->client_pf.rbits = ctpopl(red_max);
9f64916d
GH
2218 vs->client_pf.rshift = red_shift;
2219 vs->client_pf.rmask = red_max << red_shift;
4c65fed8 2220 vs->client_pf.gmax = green_max ? green_max : 0xFF;
7c9209e7 2221 vs->client_pf.gbits = ctpopl(green_max);
9f64916d
GH
2222 vs->client_pf.gshift = green_shift;
2223 vs->client_pf.gmask = green_max << green_shift;
4c65fed8 2224 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
7c9209e7 2225 vs->client_pf.bbits = ctpopl(blue_max);
9f64916d
GH
2226 vs->client_pf.bshift = blue_shift;
2227 vs->client_pf.bmask = blue_max << blue_shift;
2228 vs->client_pf.bits_per_pixel = bits_per_pixel;
2229 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2230 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2231 vs->client_be = big_endian_flag;
6cec5487 2232
0c426e45
AG
2233 if (!true_color_flag) {
2234 send_color_map(vs);
2235 }
2236
6cec5487 2237 set_pixel_conversion(vs);
24236869 2238
1d0d59fe
GH
2239 graphic_hw_invalidate(vs->vd->dcl.con);
2240 graphic_hw_update(vs->vd->dcl.con);
24236869
FB
2241}
2242
ca4cca4d
AL
2243static void pixel_format_message (VncState *vs) {
2244 char pad[3] = { 0, 0, 0 };
2245
9f64916d
GH
2246 vs->client_pf = qemu_default_pixelformat(32);
2247
2248 vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
2249 vnc_write_u8(vs, vs->client_pf.depth); /* depth */
ca4cca4d 2250
e2542fe2 2251#ifdef HOST_WORDS_BIGENDIAN
ca4cca4d
AL
2252 vnc_write_u8(vs, 1); /* big-endian-flag */
2253#else
2254 vnc_write_u8(vs, 0); /* big-endian-flag */
2255#endif
2256 vnc_write_u8(vs, 1); /* true-color-flag */
9f64916d
GH
2257 vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
2258 vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
2259 vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
2260 vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
2261 vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
2262 vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
2263 vnc_write(vs, pad, 3); /* padding */
70a4568f
CC
2264
2265 vnc_hextile_set_pixel_conversion(vs, 0);
ca4cca4d 2266 vs->write_pixels = vnc_write_pixels_copy;
ca4cca4d
AL
2267}
2268
753b4053 2269static void vnc_colordepth(VncState *vs)
7eac3a87 2270{
753b4053 2271 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
ca4cca4d 2272 /* Sending a WMVi message to notify the client*/
bd023f95 2273 vnc_lock_output(vs);
46a183da 2274 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
ca4cca4d
AL
2275 vnc_write_u8(vs, 0);
2276 vnc_write_u16(vs, 1); /* number of rects */
d39fa6d8 2277 vnc_framebuffer_update(vs, 0, 0,
bea60dd7
PL
2278 pixman_image_get_width(vs->vd->server),
2279 pixman_image_get_height(vs->vd->server),
d39fa6d8 2280 VNC_ENCODING_WMVi);
ca4cca4d 2281 pixel_format_message(vs);
bd023f95 2282 vnc_unlock_output(vs);
ca4cca4d 2283 vnc_flush(vs);
7eac3a87 2284 } else {
6cec5487 2285 set_pixel_conversion(vs);
7eac3a87
AL
2286 }
2287}
2288
60fe76f3 2289static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
24236869
FB
2290{
2291 int i;
2292 uint16_t limit;
cf070658 2293 uint32_t freq;
2430ffe4
SS
2294 VncDisplay *vd = vs->vd;
2295
2296 if (data[0] > 3) {
0f7b2864 2297 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2430ffe4 2298 }
24236869
FB
2299
2300 switch (data[0]) {
46a183da 2301 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
28a76be8
AL
2302 if (len == 1)
2303 return 20;
2304
ec9fb41a 2305 set_pixel_format(vs, read_u8(data, 4),
28a76be8
AL
2306 read_u8(data, 6), read_u8(data, 7),
2307 read_u16(data, 8), read_u16(data, 10),
2308 read_u16(data, 12), read_u8(data, 14),
2309 read_u8(data, 15), read_u8(data, 16));
2310 break;
46a183da 2311 case VNC_MSG_CLIENT_SET_ENCODINGS:
28a76be8
AL
2312 if (len == 1)
2313 return 4;
24236869 2314
28a76be8 2315 if (len == 4) {
69dd5c9f
AL
2316 limit = read_u16(data, 2);
2317 if (limit > 0)
2318 return 4 + (limit * 4);
2319 } else
2320 limit = read_u16(data, 2);
24236869 2321
28a76be8
AL
2322 for (i = 0; i < limit; i++) {
2323 int32_t val = read_s32(data, 4 + (i * 4));
2324 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2325 }
24236869 2326
28a76be8
AL
2327 set_encodings(vs, (int32_t *)(data + 4), limit);
2328 break;
46a183da 2329 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
28a76be8
AL
2330 if (len == 1)
2331 return 10;
24236869 2332
28a76be8
AL
2333 framebuffer_update_request(vs,
2334 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2335 read_u16(data, 6), read_u16(data, 8));
2336 break;
46a183da 2337 case VNC_MSG_CLIENT_KEY_EVENT:
28a76be8
AL
2338 if (len == 1)
2339 return 8;
24236869 2340
28a76be8
AL
2341 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2342 break;
46a183da 2343 case VNC_MSG_CLIENT_POINTER_EVENT:
28a76be8
AL
2344 if (len == 1)
2345 return 6;
24236869 2346
28a76be8
AL
2347 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2348 break;
46a183da 2349 case VNC_MSG_CLIENT_CUT_TEXT:
f9a70e79 2350 if (len == 1) {
28a76be8 2351 return 8;
f9a70e79 2352 }
28a76be8 2353 if (len == 8) {
baa7666c 2354 uint32_t dlen = read_u32(data, 4);
f9a70e79
PL
2355 if (dlen > (1 << 20)) {
2356 error_report("vnc: client_cut_text msg payload has %u bytes"
2357 " which exceeds our limit of 1MB.", dlen);
2358 vnc_client_error(vs);
2359 break;
2360 }
2361 if (dlen > 0) {
baa7666c 2362 return 8 + dlen;
f9a70e79 2363 }
baa7666c 2364 }
24236869 2365
28a76be8
AL
2366 client_cut_text(vs, read_u32(data, 4), data + 8);
2367 break;
46a183da 2368 case VNC_MSG_CLIENT_QEMU:
9ca313aa
AL
2369 if (len == 1)
2370 return 2;
2371
2372 switch (read_u8(data, 1)) {
46a183da 2373 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
9ca313aa
AL
2374 if (len == 2)
2375 return 12;
2376
2377 ext_key_event(vs, read_u16(data, 2),
2378 read_u32(data, 4), read_u32(data, 8));
2379 break;
46a183da 2380 case VNC_MSG_CLIENT_QEMU_AUDIO:
429a8ed3 2381 if (len == 2)
2382 return 4;
2383
2384 switch (read_u16 (data, 2)) {
46a183da 2385 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
429a8ed3 2386 audio_add(vs);
2387 break;
46a183da 2388 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
429a8ed3 2389 audio_del(vs);
2390 break;
46a183da 2391 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
429a8ed3 2392 if (len == 4)
2393 return 10;
2394 switch (read_u8(data, 4)) {
2395 case 0: vs->as.fmt = AUD_FMT_U8; break;
2396 case 1: vs->as.fmt = AUD_FMT_S8; break;
2397 case 2: vs->as.fmt = AUD_FMT_U16; break;
2398 case 3: vs->as.fmt = AUD_FMT_S16; break;
2399 case 4: vs->as.fmt = AUD_FMT_U32; break;
2400 case 5: vs->as.fmt = AUD_FMT_S32; break;
2401 default:
153130cd 2402 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
429a8ed3 2403 vnc_client_error(vs);
2404 break;
2405 }
2406 vs->as.nchannels = read_u8(data, 5);
2407 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
090fdc83 2408 VNC_DEBUG("Invalid audio channel count %d\n",
153130cd 2409 read_u8(data, 5));
429a8ed3 2410 vnc_client_error(vs);
2411 break;
2412 }
cf070658
DB
2413 freq = read_u32(data, 6);
2414 /* No official limit for protocol, but 48khz is a sensible
2415 * upper bound for trustworthy clients, and this limit
2416 * protects calculations involving 'vs->as.freq' later.
2417 */
2418 if (freq > 48000) {
2419 VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
2420 vnc_client_error(vs);
2421 break;
2422 }
2423 vs->as.freq = freq;
429a8ed3 2424 break;
2425 default:
153130cd 2426 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
429a8ed3 2427 vnc_client_error(vs);
2428 break;
2429 }
2430 break;
2431
9ca313aa 2432 default:
153130cd 2433 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
9ca313aa
AL
2434 vnc_client_error(vs);
2435 break;
2436 }
2437 break;
24236869 2438 default:
153130cd 2439 VNC_DEBUG("Msg: %d\n", data[0]);
28a76be8
AL
2440 vnc_client_error(vs);
2441 break;
24236869 2442 }
5fafdf24 2443
e2b72cb6 2444 vnc_update_throttle_offset(vs);
24236869
FB
2445 vnc_read_when(vs, protocol_client_msg, 1);
2446 return 0;
2447}
2448
60fe76f3 2449static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869 2450{
c35734b2 2451 char buf[1024];
8cf36489 2452 VncShareMode mode;
c35734b2 2453 int size;
24236869 2454
8cf36489
GH
2455 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2456 switch (vs->vd->share_policy) {
2457 case VNC_SHARE_POLICY_IGNORE:
2458 /*
2459 * Ignore the shared flag. Nothing to do here.
2460 *
2461 * Doesn't conform to the rfb spec but is traditional qemu
2462 * behavior, thus left here as option for compatibility
2463 * reasons.
2464 */
2465 break;
2466 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2467 /*
2468 * Policy: Allow clients ask for exclusive access.
2469 *
2470 * Implementation: When a client asks for exclusive access,
2471 * disconnect all others. Shared connects are allowed as long
2472 * as no exclusive connection exists.
2473 *
2474 * This is how the rfb spec suggests to handle the shared flag.
2475 */
2476 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2477 VncState *client;
2478 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2479 if (vs == client) {
2480 continue;
2481 }
2482 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2483 client->share_mode != VNC_SHARE_MODE_SHARED) {
2484 continue;
2485 }
2486 vnc_disconnect_start(client);
2487 }
2488 }
2489 if (mode == VNC_SHARE_MODE_SHARED) {
2490 if (vs->vd->num_exclusive > 0) {
2491 vnc_disconnect_start(vs);
2492 return 0;
2493 }
2494 }
2495 break;
2496 case VNC_SHARE_POLICY_FORCE_SHARED:
2497 /*
2498 * Policy: Shared connects only.
2499 * Implementation: Disallow clients asking for exclusive access.
2500 *
2501 * Useful for shared desktop sessions where you don't want
2502 * someone forgetting to say -shared when running the vnc
2503 * client disconnect everybody else.
2504 */
2505 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2506 vnc_disconnect_start(vs);
2507 return 0;
2508 }
2509 break;
2510 }
2511 vnc_set_share_mode(vs, mode);
2512
e5f34cdd
GH
2513 if (vs->vd->num_shared > vs->vd->connections_limit) {
2514 vnc_disconnect_start(vs);
2515 return 0;
2516 }
2517
4c956bd8
DB
2518 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
2519 pixman_image_get_width(vs->vd->server) >= 0);
2520 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
2521 pixman_image_get_height(vs->vd->server) >= 0);
bea60dd7
PL
2522 vs->client_width = pixman_image_get_width(vs->vd->server);
2523 vs->client_height = pixman_image_get_height(vs->vd->server);
5862d195
GH
2524 vnc_write_u16(vs, vs->client_width);
2525 vnc_write_u16(vs, vs->client_height);
24236869 2526
ca4cca4d 2527 pixel_format_message(vs);
24236869 2528
97efe4f9 2529 if (qemu_name) {
c35734b2 2530 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
97efe4f9
TH
2531 if (size > sizeof(buf)) {
2532 size = sizeof(buf);
2533 }
2534 } else {
c35734b2 2535 size = snprintf(buf, sizeof(buf), "QEMU");
97efe4f9 2536 }
c35734b2
TS
2537
2538 vnc_write_u32(vs, size);
2539 vnc_write(vs, buf, size);
24236869
FB
2540 vnc_flush(vs);
2541
4a80dba3 2542 vnc_client_cache_auth(vs);
fb6ba0d5 2543 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
4a80dba3 2544
24236869
FB
2545 vnc_read_when(vs, protocol_client_msg, 1);
2546
2547 return 0;
2548}
2549
5fb6c7a8
AL
2550void start_client_init(VncState *vs)
2551{
2552 vnc_read_when(vs, protocol_client_init, 1);
2553}
2554
70848515
TS
2555static void make_challenge(VncState *vs)
2556{
2557 int i;
2558
2559 srand(time(NULL)+getpid()+getpid()*987654+rand());
2560
2561 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
2562 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
2563}
2564
60fe76f3 2565static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 2566{
60fe76f3 2567 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
800567a6 2568 size_t i, pwlen;
60fe76f3 2569 unsigned char key[8];
3c9405a0 2570 time_t now = time(NULL);
60928458 2571 QCryptoCipher *cipher = NULL;
800567a6 2572 Error *err = NULL;
70848515 2573
1cd20f8b 2574 if (!vs->vd->password) {
7364dbda 2575 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
6bffdf0f 2576 goto reject;
70848515 2577 }
3c9405a0 2578 if (vs->vd->expires < now) {
7364dbda 2579 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
3c9405a0
GH
2580 goto reject;
2581 }
70848515
TS
2582
2583 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2584
2585 /* Calculate the expected challenge response */
753b4053 2586 pwlen = strlen(vs->vd->password);
70848515 2587 for (i=0; i<sizeof(key); i++)
753b4053 2588 key[i] = i<pwlen ? vs->vd->password[i] : 0;
800567a6
DB
2589
2590 cipher = qcrypto_cipher_new(
2591 QCRYPTO_CIPHER_ALG_DES_RFB,
2592 QCRYPTO_CIPHER_MODE_ECB,
2593 key, G_N_ELEMENTS(key),
2594 &err);
2595 if (!cipher) {
7364dbda
DB
2596 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2597 error_get_pretty(err));
800567a6
DB
2598 error_free(err);
2599 goto reject;
2600 }
2601
a1695137 2602 if (qcrypto_cipher_encrypt(cipher,
800567a6
DB
2603 vs->challenge,
2604 response,
2605 VNC_AUTH_CHALLENGE_SIZE,
2606 &err) < 0) {
7364dbda
DB
2607 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2608 error_get_pretty(err));
800567a6
DB
2609 error_free(err);
2610 goto reject;
2611 }
70848515
TS
2612
2613 /* Compare expected vs actual challenge response */
2614 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
7364dbda 2615 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
6bffdf0f 2616 goto reject;
70848515 2617 } else {
7364dbda 2618 trace_vnc_auth_pass(vs, vs->auth);
28a76be8
AL
2619 vnc_write_u32(vs, 0); /* Accept auth */
2620 vnc_flush(vs);
70848515 2621
5fb6c7a8 2622 start_client_init(vs);
70848515 2623 }
60928458
GA
2624
2625 qcrypto_cipher_free(cipher);
70848515 2626 return 0;
6bffdf0f
GH
2627
2628reject:
2629 vnc_write_u32(vs, 1); /* Reject auth */
2630 if (vs->minor >= 8) {
2631 static const char err[] = "Authentication failed";
2632 vnc_write_u32(vs, sizeof(err));
2633 vnc_write(vs, err, sizeof(err));
2634 }
2635 vnc_flush(vs);
2636 vnc_client_error(vs);
60928458 2637 qcrypto_cipher_free(cipher);
6bffdf0f 2638 return 0;
70848515
TS
2639}
2640
5fb6c7a8 2641void start_auth_vnc(VncState *vs)
70848515
TS
2642{
2643 make_challenge(vs);
2644 /* Send client a 'random' challenge */
2645 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2646 vnc_flush(vs);
2647
2648 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
469b15c6
TS
2649}
2650
2651
60fe76f3 2652static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
2653{
2654 /* We only advertise 1 auth scheme at a time, so client
2655 * must pick the one we sent. Verify this */
7e7e2ebc 2656 if (data[0] != vs->auth) { /* Reject auth */
7364dbda 2657 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
70848515
TS
2658 vnc_write_u32(vs, 1);
2659 if (vs->minor >= 8) {
2660 static const char err[] = "Authentication failed";
2661 vnc_write_u32(vs, sizeof(err));
2662 vnc_write(vs, err, sizeof(err));
2663 }
2664 vnc_client_error(vs);
2665 } else { /* Accept requested auth */
7364dbda 2666 trace_vnc_auth_start(vs, vs->auth);
7e7e2ebc 2667 switch (vs->auth) {
70848515 2668 case VNC_AUTH_NONE:
a26c97ad
AZ
2669 if (vs->minor >= 8) {
2670 vnc_write_u32(vs, 0); /* Accept auth completion */
2671 vnc_flush(vs);
2672 }
7364dbda 2673 trace_vnc_auth_pass(vs, vs->auth);
5fb6c7a8 2674 start_client_init(vs);
70848515
TS
2675 break;
2676
2677 case VNC_AUTH_VNC:
5fb6c7a8
AL
2678 start_auth_vnc(vs);
2679 break;
70848515 2680
8d5d2d4c 2681 case VNC_AUTH_VENCRYPT:
5fb6c7a8
AL
2682 start_auth_vencrypt(vs);
2683 break;
8d5d2d4c 2684
2f9606b3
AL
2685#ifdef CONFIG_VNC_SASL
2686 case VNC_AUTH_SASL:
2f9606b3
AL
2687 start_auth_sasl(vs);
2688 break;
2689#endif /* CONFIG_VNC_SASL */
2690
70848515 2691 default: /* Should not be possible, but just in case */
7364dbda 2692 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
70848515
TS
2693 vnc_write_u8(vs, 1);
2694 if (vs->minor >= 8) {
2695 static const char err[] = "Authentication failed";
2696 vnc_write_u32(vs, sizeof(err));
2697 vnc_write(vs, err, sizeof(err));
2698 }
2699 vnc_client_error(vs);
2700 }
2701 }
2702 return 0;
2703}
2704
60fe76f3 2705static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
2706{
2707 char local[13];
24236869
FB
2708
2709 memcpy(local, version, 12);
2710 local[12] = 0;
2711
70848515 2712 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
28a76be8
AL
2713 VNC_DEBUG("Malformed protocol version %s\n", local);
2714 vnc_client_error(vs);
2715 return 0;
24236869 2716 }
70848515
TS
2717 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2718 if (vs->major != 3 ||
28a76be8
AL
2719 (vs->minor != 3 &&
2720 vs->minor != 4 &&
2721 vs->minor != 5 &&
2722 vs->minor != 7 &&
2723 vs->minor != 8)) {
2724 VNC_DEBUG("Unsupported client version\n");
2725 vnc_write_u32(vs, VNC_AUTH_INVALID);
2726 vnc_flush(vs);
2727 vnc_client_error(vs);
2728 return 0;
70848515 2729 }
b0566f4f 2730 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
2731 * as equivalent to v3.3 by servers
2732 */
b0566f4f 2733 if (vs->minor == 4 || vs->minor == 5)
28a76be8 2734 vs->minor = 3;
70848515
TS
2735
2736 if (vs->minor == 3) {
7364dbda 2737 trace_vnc_auth_start(vs, vs->auth);
7e7e2ebc 2738 if (vs->auth == VNC_AUTH_NONE) {
7e7e2ebc 2739 vnc_write_u32(vs, vs->auth);
70848515 2740 vnc_flush(vs);
7364dbda 2741 trace_vnc_auth_pass(vs, vs->auth);
28a76be8 2742 start_client_init(vs);
7e7e2ebc 2743 } else if (vs->auth == VNC_AUTH_VNC) {
70848515 2744 VNC_DEBUG("Tell client VNC auth\n");
7e7e2ebc 2745 vnc_write_u32(vs, vs->auth);
70848515
TS
2746 vnc_flush(vs);
2747 start_auth_vnc(vs);
2748 } else {
7364dbda
DB
2749 trace_vnc_auth_fail(vs, vs->auth,
2750 "Unsupported auth method for v3.3", "");
70848515
TS
2751 vnc_write_u32(vs, VNC_AUTH_INVALID);
2752 vnc_flush(vs);
2753 vnc_client_error(vs);
2754 }
2755 } else {
28a76be8 2756 vnc_write_u8(vs, 1); /* num auth */
7e7e2ebc 2757 vnc_write_u8(vs, vs->auth);
28a76be8
AL
2758 vnc_read_when(vs, protocol_client_auth, 1);
2759 vnc_flush(vs);
70848515 2760 }
24236869
FB
2761
2762 return 0;
2763}
2764
999342a0
CC
2765static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2766{
2767 struct VncSurface *vs = &vd->guest;
2768
2769 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2770}
2771
7d964c9d
CC
2772void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2773{
2774 int i, j;
2775
2776 w = (x + w) / VNC_STAT_RECT;
2777 h = (y + h) / VNC_STAT_RECT;
2778 x /= VNC_STAT_RECT;
2779 y /= VNC_STAT_RECT;
2780
207f328a
CC
2781 for (j = y; j <= h; j++) {
2782 for (i = x; i <= w; i++) {
7d964c9d
CC
2783 vs->lossy_rect[j][i] = 1;
2784 }
2785 }
2786}
2787
2788static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2789{
2790 VncState *vs;
2791 int sty = y / VNC_STAT_RECT;
2792 int stx = x / VNC_STAT_RECT;
2793 int has_dirty = 0;
2794
5a3804db
MAL
2795 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2796 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
7d964c9d
CC
2797
2798 QTAILQ_FOREACH(vs, &vd->clients, next) {
bc2429b9 2799 int j;
7d964c9d
CC
2800
2801 /* kernel send buffers are full -> refresh later */
2802 if (vs->output.offset) {
2803 continue;
2804 }
2805
2806 if (!vs->lossy_rect[sty][stx]) {
2807 continue;
2808 }
207f328a 2809
7d964c9d
CC
2810 vs->lossy_rect[sty][stx] = 0;
2811 for (j = 0; j < VNC_STAT_RECT; ++j) {
b4c85ddc
PL
2812 bitmap_set(vs->dirty[y + j],
2813 x / VNC_DIRTY_PIXELS_PER_BIT,
2814 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
7d964c9d
CC
2815 }
2816 has_dirty++;
2817 }
207f328a 2818
7d964c9d
CC
2819 return has_dirty;
2820}
2821
2822static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
999342a0 2823{
eebe0b79
GH
2824 int width = MIN(pixman_image_get_width(vd->guest.fb),
2825 pixman_image_get_width(vd->server));
2826 int height = MIN(pixman_image_get_height(vd->guest.fb),
2827 pixman_image_get_height(vd->server));
999342a0
CC
2828 int x, y;
2829 struct timeval res;
7d964c9d 2830 int has_dirty = 0;
999342a0 2831
9f64916d
GH
2832 for (y = 0; y < height; y += VNC_STAT_RECT) {
2833 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
2834 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2835
2836 rect->updated = false;
2837 }
2838 }
2839
ad620c29 2840 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
999342a0
CC
2841
2842 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
7d964c9d 2843 return has_dirty;
999342a0
CC
2844 }
2845 vd->guest.last_freq_check = *tv;
2846
9f64916d
GH
2847 for (y = 0; y < height; y += VNC_STAT_RECT) {
2848 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
2849 VncRectStat *rect= vnc_stat_rect(vd, x, y);
2850 int count = ARRAY_SIZE(rect->times);
2851 struct timeval min, max;
2852
2853 if (!timerisset(&rect->times[count - 1])) {
2854 continue ;
2855 }
2856
2857 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 2858 qemu_timersub(tv, &max, &res);
999342a0
CC
2859
2860 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
2861 rect->freq = 0;
7d964c9d 2862 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
999342a0
CC
2863 memset(rect->times, 0, sizeof (rect->times));
2864 continue ;
2865 }
2866
2867 min = rect->times[rect->idx];
2868 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 2869 qemu_timersub(&max, &min, &res);
999342a0
CC
2870
2871 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
2872 rect->freq /= count;
2873 rect->freq = 1. / rect->freq;
2874 }
2875 }
7d964c9d 2876 return has_dirty;
999342a0
CC
2877}
2878
2879double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
2880{
2881 int i, j;
2882 double total = 0;
2883 int num = 0;
2884
5a3804db
MAL
2885 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2886 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
999342a0
CC
2887
2888 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
2889 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
2890 total += vnc_stat_rect(vs->vd, i, j)->freq;
2891 num++;
2892 }
2893 }
2894
2895 if (num) {
2896 return total / num;
2897 } else {
2898 return 0;
2899 }
2900}
2901
2902static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
2903{
2904 VncRectStat *rect;
2905
2906 rect = vnc_stat_rect(vd, x, y);
2907 if (rect->updated) {
2908 return ;
2909 }
2910 rect->times[rect->idx] = *tv;
2911 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
2912 rect->updated = true;
2913}
2914
1fc62412
SS
2915static int vnc_refresh_server_surface(VncDisplay *vd)
2916{
bea60dd7
PL
2917 int width = MIN(pixman_image_get_width(vd->guest.fb),
2918 pixman_image_get_width(vd->server));
2919 int height = MIN(pixman_image_get_height(vd->guest.fb),
2920 pixman_image_get_height(vd->server));
eb8934b0 2921 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
12b316d4 2922 uint8_t *guest_row0 = NULL, *server_row0;
41b4bef6 2923 VncState *vs;
1fc62412 2924 int has_dirty = 0;
9f64916d 2925 pixman_image_t *tmpbuf = NULL;
1fc62412 2926
80e0c8c3 2927 struct timeval tv = { 0, 0 };
999342a0 2928
80e0c8c3
CC
2929 if (!vd->non_adaptive) {
2930 gettimeofday(&tv, NULL);
2931 has_dirty = vnc_update_stats(vd, &tv);
2932 }
999342a0 2933
1fc62412
SS
2934 /*
2935 * Walk through the guest dirty map.
2936 * Check and copy modified bits from guest to server surface.
2937 * Update server dirty map.
2938 */
bea60dd7 2939 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
eb8934b0
GH
2940 server_stride = guest_stride = guest_ll =
2941 pixman_image_get_stride(vd->server);
bea60dd7
PL
2942 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
2943 server_stride);
9f64916d
GH
2944 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2945 int width = pixman_image_get_width(vd->server);
2946 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
12b316d4 2947 } else {
eb8934b0
GH
2948 int guest_bpp =
2949 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
12b316d4
PL
2950 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
2951 guest_stride = pixman_image_get_stride(vd->guest.fb);
659c90ee 2952 guest_ll = pixman_image_get_width(vd->guest.fb) * (DIV_ROUND_UP(guest_bpp, 8));
12b316d4 2953 }
eb8934b0 2954 line_bytes = MIN(server_stride, guest_ll);
12b316d4 2955
12b316d4
PL
2956 for (;;) {
2957 int x;
2958 uint8_t *guest_ptr, *server_ptr;
2959 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
2960 height * VNC_DIRTY_BPL(&vd->guest),
2961 y * VNC_DIRTY_BPL(&vd->guest));
2962 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
2963 /* no more dirty bits */
2964 break;
2965 }
2966 y = offset / VNC_DIRTY_BPL(&vd->guest);
2967 x = offset % VNC_DIRTY_BPL(&vd->guest);
1fc62412 2968
12b316d4
PL
2969 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
2970
2971 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
2972 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
2973 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
2974 } else {
2975 guest_ptr = guest_row0 + y * guest_stride;
2976 }
2977 guest_ptr += x * cmp_bytes;
2978
2979 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
2980 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
bea60dd7 2981 int _cmp_bytes = cmp_bytes;
12b316d4
PL
2982 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
2983 continue;
2984 }
eb8934b0
GH
2985 if ((x + 1) * cmp_bytes > line_bytes) {
2986 _cmp_bytes = line_bytes - x * cmp_bytes;
bea60dd7 2987 }
eb8934b0 2988 assert(_cmp_bytes >= 0);
bea60dd7 2989 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
12b316d4
PL
2990 continue;
2991 }
bea60dd7 2992 memcpy(server_ptr, guest_ptr, _cmp_bytes);
12b316d4
PL
2993 if (!vd->non_adaptive) {
2994 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
2995 y, &tv);
1fc62412 2996 }
12b316d4
PL
2997 QTAILQ_FOREACH(vs, &vd->clients, next) {
2998 set_bit(x, vs->dirty[y]);
2999 }
3000 has_dirty++;
1fc62412 3001 }
12b316d4
PL
3002
3003 y++;
1fc62412 3004 }
9f64916d 3005 qemu_pixman_image_unref(tmpbuf);
1fc62412
SS
3006 return has_dirty;
3007}
3008
0f7b2864 3009static void vnc_refresh(DisplayChangeListener *dcl)
703bc68f 3010{
0f7b2864 3011 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
41b4bef6
AS
3012 VncState *vs, *vn;
3013 int has_dirty, rects = 0;
703bc68f 3014
9d6b2070
C
3015 if (QTAILQ_EMPTY(&vd->clients)) {
3016 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
3017 return;
3018 }
3019
1d0d59fe 3020 graphic_hw_update(vd->dcl.con);
703bc68f 3021
bd023f95 3022 if (vnc_trylock_display(vd)) {
0f7b2864 3023 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
bd023f95
CC
3024 return;
3025 }
3026
1fc62412 3027 has_dirty = vnc_refresh_server_surface(vd);
bd023f95 3028 vnc_unlock_display(vd);
1fc62412 3029
41b4bef6 3030 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
6af998db 3031 rects += vnc_update_client(vs, has_dirty);
6185c578 3032 /* vs might be free()ed here */
703bc68f 3033 }
bd023f95 3034
2430ffe4 3035 if (has_dirty && rects) {
0f7b2864
GH
3036 vd->dcl.update_interval /= 2;
3037 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
3038 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3039 }
2430ffe4 3040 } else {
0f7b2864
GH
3041 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3042 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3043 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3044 }
703bc68f
SS
3045 }
3046}
3047
04d2529d 3048static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2c8cf549 3049 bool skipauth, bool websocket)
3aa3eea3 3050{
fedf0d35 3051 VncState *vs = g_new0(VncState, 1);
90cd03a3 3052 bool first_client = QTAILQ_EMPTY(&vd->clients);
7d964c9d
CC
3053 int i;
3054
ad6374c4 3055 trace_vnc_client_connect(vs, sioc);
04d2529d
DB
3056 vs->sioc = sioc;
3057 object_ref(OBJECT(vs->sioc));
3058 vs->ioc = QIO_CHANNEL(sioc);
3059 object_ref(OBJECT(vs->ioc));
d616ccc5 3060 vs->vd = vd;
7e7e2ebc 3061
04d2529d
DB
3062 buffer_init(&vs->input, "vnc-input/%p", sioc);
3063 buffer_init(&vs->output, "vnc-output/%p", sioc);
04d2529d 3064 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
543b9580 3065
04d2529d
DB
3066 buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
3067 buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
3068 buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
543b9580 3069#ifdef CONFIG_VNC_JPEG
04d2529d 3070 buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
543b9580
GH
3071#endif
3072#ifdef CONFIG_VNC_PNG
04d2529d 3073 buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
543b9580 3074#endif
04d2529d
DB
3075 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
3076 buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
3077 buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
3078 buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
543b9580 3079
7e7e2ebc
DB
3080 if (skipauth) {
3081 vs->auth = VNC_AUTH_NONE;
7e7e2ebc 3082 vs->subauth = VNC_AUTH_INVALID;
7e7e2ebc 3083 } else {
f9148c8a
DB
3084 if (websocket) {
3085 vs->auth = vd->ws_auth;
3086 vs->subauth = VNC_AUTH_INVALID;
3087 } else {
3088 vs->auth = vd->auth;
3089 vs->subauth = vd->subauth;
3090 }
7e7e2ebc 3091 }
04d2529d
DB
3092 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3093 sioc, websocket, vs->auth, vs->subauth);
7e7e2ebc 3094
7267c094 3095 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
7d964c9d 3096 for (i = 0; i < VNC_STAT_ROWS; ++i) {
fedf0d35 3097 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
7d964c9d 3098 }
753b4053 3099
04d2529d 3100 VNC_DEBUG("New client on socket %p\n", vs->sioc);
0f7b2864 3101 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
04d2529d 3102 qio_channel_set_blocking(vs->ioc, false, NULL);
a75d6f07
BC
3103 if (vs->ioc_tag) {
3104 g_source_remove(vs->ioc_tag);
3105 }
7536ee4b
TH
3106 if (websocket) {
3107 vs->websocket = 1;
38e5756a 3108 if (vd->tlscreds) {
04d2529d
DB
3109 vs->ioc_tag = qio_channel_add_watch(
3110 vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
3e305e4a 3111 } else {
04d2529d
DB
3112 vs->ioc_tag = qio_channel_add_watch(
3113 vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
0057a0d5 3114 }
04d2529d
DB
3115 } else {
3116 vs->ioc_tag = qio_channel_add_watch(
3117 vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
7536ee4b 3118 }
753b4053 3119
4a80dba3 3120 vnc_client_cache_addr(vs);
fb6ba0d5 3121 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
8cf36489 3122 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
4a80dba3 3123
753b4053
AL
3124 vs->last_x = -1;
3125 vs->last_y = -1;
3126
3127 vs->as.freq = 44100;
3128 vs->as.nchannels = 2;
3129 vs->as.fmt = AUD_FMT_S16;
3130 vs->as.endianness = 0;
3131
bd023f95 3132 qemu_mutex_init(&vs->output_mutex);
175b2a6e 3133 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
bd023f95 3134
e5f34cdd 3135 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
c7628bff
GH
3136 if (first_client) {
3137 vnc_update_server_surface(vd);
3138 }
1fc62412 3139
1d0d59fe 3140 graphic_hw_update(vd->dcl.con);
1fc62412 3141
90cd03a3 3142 if (!vs->websocket) {
dbee9897 3143 vnc_start_protocol(vs);
90cd03a3
DB
3144 }
3145
3146 if (vd->num_connecting > vd->connections_limit) {
3147 QTAILQ_FOREACH(vs, &vd->clients, next) {
3148 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3149 vnc_disconnect_start(vs);
3150 return;
3151 }
3152 }
3153 }
3154}
3155
dbee9897 3156void vnc_start_protocol(VncState *vs)
90cd03a3 3157{
3aa3eea3
AZ
3158 vnc_write(vs, "RFB 003.008\n", 12);
3159 vnc_flush(vs);
3160 vnc_read_when(vs, protocol_version, 12);
753b4053 3161
37c34d9d
AL
3162 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3163 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3aa3eea3
AZ
3164}
3165
13e1d0e7
DB
3166static void vnc_listen_io(QIONetListener *listener,
3167 QIOChannelSocket *cioc,
3168 void *opaque)
24236869 3169{
bf01c179 3170 VncDisplay *vd = opaque;
13e1d0e7 3171 bool isWebsock = listener == vd->wslistener;
7536ee4b 3172
13e1d0e7
DB
3173 qio_channel_set_name(QIO_CHANNEL(cioc),
3174 isWebsock ? "vnc-ws-server" : "vnc-server");
3175 qio_channel_set_delay(QIO_CHANNEL(cioc), false);
3176 vnc_connect(vd, cioc, false, isWebsock);
7536ee4b 3177}
7536ee4b 3178
7c20b4a3 3179static const DisplayChangeListenerOps dcl_ops = {
34da30af
BH
3180 .dpy_name = "vnc",
3181 .dpy_refresh = vnc_refresh,
34da30af
BH
3182 .dpy_gfx_update = vnc_dpy_update,
3183 .dpy_gfx_switch = vnc_dpy_switch,
3184 .dpy_gfx_check_format = qemu_pixman_check_format,
3185 .dpy_mouse_set = vnc_mouse_set,
3186 .dpy_cursor_define = vnc_dpy_cursor_define,
7c20b4a3
GH
3187};
3188
14f7143e 3189void vnc_display_init(const char *id)
24236869 3190{
bf01c179 3191 VncDisplay *vd;
4db14629
GH
3192
3193 if (vnc_display_find(id) != NULL) {
3194 return;
3195 }
bf01c179 3196 vd = g_malloc0(sizeof(*vd));
24236869 3197
bf01c179
DB
3198 vd->id = strdup(id);
3199 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
24236869 3200
bf01c179
DB
3201 QTAILQ_INIT(&vd->clients);
3202 vd->expires = TIME_MAX;
24236869 3203
40066175
GH
3204 if (keyboard_layout) {
3205 trace_vnc_key_map_init(keyboard_layout);
bf01c179 3206 vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
40066175 3207 } else {
bf01c179 3208 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
40066175 3209 }
24236869 3210
bf01c179 3211 if (!vd->kbd_layout) {
28a76be8 3212 exit(1);
bf01c179 3213 }
24236869 3214
bf01c179
DB
3215 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3216 vd->connections_limit = 32;
12e29b16 3217
bf01c179 3218 qemu_mutex_init(&vd->mutex);
bd023f95 3219 vnc_start_worker_thread();
bd023f95 3220
bf01c179
DB
3221 vd->dcl.ops = &dcl_ops;
3222 register_displaychangelistener(&vd->dcl);
71cab5ca
TS
3223}
3224
6f43024c 3225
bf01c179 3226static void vnc_display_close(VncDisplay *vd)
71cab5ca 3227{
bf01c179 3228 if (!vd) {
452b4d88 3229 return;
bf01c179
DB
3230 }
3231 vd->is_unix = false;
13e1d0e7
DB
3232
3233 if (vd->listener) {
3234 qio_net_listener_disconnect(vd->listener);
3235 object_unref(OBJECT(vd->listener));
71cab5ca 3236 }
13e1d0e7 3237 vd->listener = NULL;
4ee74fa7 3238
13e1d0e7
DB
3239 if (vd->wslistener) {
3240 qio_net_listener_disconnect(vd->wslistener);
3241 object_unref(OBJECT(vd->wslistener));
7536ee4b 3242 }
13e1d0e7 3243 vd->wslistener = NULL;
4ee74fa7 3244
bf01c179
DB
3245 vd->auth = VNC_AUTH_INVALID;
3246 vd->subauth = VNC_AUTH_INVALID;
3247 if (vd->tlscreds) {
3248 object_unparent(OBJECT(vd->tlscreds));
3249 vd->tlscreds = NULL;
3e305e4a 3250 }
bf01c179
DB
3251 g_free(vd->tlsaclname);
3252 vd->tlsaclname = NULL;
a54f0d2b
PO
3253 if (vd->lock_key_sync) {
3254 qemu_remove_led_event_handler(vd->led);
2dc120be 3255 vd->led = NULL;
a54f0d2b 3256 }
70848515
TS
3257}
3258
14f7143e 3259int vnc_display_password(const char *id, const char *password)
70848515 3260{
bf01c179 3261 VncDisplay *vd = vnc_display_find(id);
70848515 3262
bf01c179 3263 if (!vd) {
a6aa9d3e 3264 return -EINVAL;
7ef92331 3265 }
bf01c179 3266 if (vd->auth == VNC_AUTH_NONE) {
cf864569 3267 error_printf_unless_qmp("If you want use passwords please enable "
7ea7d36e 3268 "password auth using '-vnc ${dpy},password'.\n");
cf864569 3269 return -EINVAL;
1cd20f8b
AL
3270 }
3271
bf01c179
DB
3272 g_free(vd->password);
3273 vd->password = g_strdup(password);
a6aa9d3e
LC
3274
3275 return 0;
71cab5ca
TS
3276}
3277
14f7143e 3278int vnc_display_pw_expire(const char *id, time_t expires)
3c9405a0 3279{
bf01c179 3280 VncDisplay *vd = vnc_display_find(id);
3c9405a0 3281
bf01c179 3282 if (!vd) {
1643f2b2
GH
3283 return -EINVAL;
3284 }
3285
bf01c179 3286 vd->expires = expires;
3c9405a0
GH
3287 return 0;
3288}
3289
bf01c179 3290static void vnc_display_print_local_addr(VncDisplay *vd)
f92f8afe 3291{
bd269ebc 3292 SocketAddress *addr;
04d2529d 3293 Error *err = NULL;
d616ccc5 3294
13e1d0e7 3295 if (!vd->listener || !vd->listener->nsioc) {
4ee74fa7
DB
3296 return;
3297 }
3298
13e1d0e7 3299 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], &err);
04d2529d 3300 if (!addr) {
33df7bf3 3301 return;
04d2529d
DB
3302 }
3303
bd269ebc
MA
3304 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3305 qapi_free_SocketAddress(addr);
33df7bf3 3306 return;
04d2529d 3307 }
33df7bf3 3308 error_printf_unless_qmp("VNC server running on %s:%s\n",
bd269ebc
MA
3309 addr->u.inet.host,
3310 addr->u.inet.port);
3311 qapi_free_SocketAddress(addr);
f92f8afe
AL
3312}
3313
4db14629
GH
3314static QemuOptsList qemu_vnc_opts = {
3315 .name = "vnc",
3316 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3317 .implied_opt_name = "vnc",
3318 .desc = {
3319 {
3320 .name = "vnc",
3321 .type = QEMU_OPT_STRING,
3322 },{
3323 .name = "websocket",
3324 .type = QEMU_OPT_STRING,
3325 },{
3e305e4a
DB
3326 .name = "tls-creds",
3327 .type = QEMU_OPT_STRING,
3328 },{
3329 /* Deprecated in favour of tls-creds */
4db14629
GH
3330 .name = "x509",
3331 .type = QEMU_OPT_STRING,
3332 },{
3333 .name = "share",
3334 .type = QEMU_OPT_STRING,
1d0d59fe
GH
3335 },{
3336 .name = "display",
3337 .type = QEMU_OPT_STRING,
3338 },{
3339 .name = "head",
3340 .type = QEMU_OPT_NUMBER,
e5f34cdd
GH
3341 },{
3342 .name = "connections",
3343 .type = QEMU_OPT_NUMBER,
88428b7a
GA
3344 },{
3345 .name = "to",
3346 .type = QEMU_OPT_NUMBER,
3347 },{
3348 .name = "ipv4",
3349 .type = QEMU_OPT_BOOL,
3350 },{
3351 .name = "ipv6",
3352 .type = QEMU_OPT_BOOL,
4db14629
GH
3353 },{
3354 .name = "password",
3355 .type = QEMU_OPT_BOOL,
3356 },{
3357 .name = "reverse",
3358 .type = QEMU_OPT_BOOL,
3359 },{
3360 .name = "lock-key-sync",
3361 .type = QEMU_OPT_BOOL,
c5ce8333
GH
3362 },{
3363 .name = "key-delay-ms",
3364 .type = QEMU_OPT_NUMBER,
4db14629
GH
3365 },{
3366 .name = "sasl",
3367 .type = QEMU_OPT_BOOL,
3368 },{
3e305e4a 3369 /* Deprecated in favour of tls-creds */
4db14629
GH
3370 .name = "tls",
3371 .type = QEMU_OPT_BOOL,
3372 },{
3e305e4a 3373 /* Deprecated in favour of tls-creds */
4db14629 3374 .name = "x509verify",
8c7d0645 3375 .type = QEMU_OPT_STRING,
4db14629
GH
3376 },{
3377 .name = "acl",
3378 .type = QEMU_OPT_BOOL,
3379 },{
3380 .name = "lossy",
3381 .type = QEMU_OPT_BOOL,
3382 },{
3383 .name = "non-adaptive",
3384 .type = QEMU_OPT_BOOL,
3385 },
3386 { /* end of list */ }
3387 },
3388};
3389
0dd72e15 3390
3e305e4a 3391static int
eda24e18
DB
3392vnc_display_setup_auth(int *auth,
3393 int *subauth,
3394 QCryptoTLSCreds *tlscreds,
0dd72e15
DB
3395 bool password,
3396 bool sasl,
3e305e4a
DB
3397 bool websocket,
3398 Error **errp)
0dd72e15
DB
3399{
3400 /*
3401 * We have a choice of 3 authentication options
3402 *
3403 * 1. none
3404 * 2. vnc
3405 * 3. sasl
3406 *
3407 * The channel can be run in 2 modes
3408 *
3409 * 1. clear
3410 * 2. tls
3411 *
3412 * And TLS can use 2 types of credentials
3413 *
3414 * 1. anon
3415 * 2. x509
3416 *
3417 * We thus have 9 possible logical combinations
3418 *
3419 * 1. clear + none
3420 * 2. clear + vnc
3421 * 3. clear + sasl
3422 * 4. tls + anon + none
3423 * 5. tls + anon + vnc
3424 * 6. tls + anon + sasl
3425 * 7. tls + x509 + none
3426 * 8. tls + x509 + vnc
3427 * 9. tls + x509 + sasl
3428 *
3429 * These need to be mapped into the VNC auth schemes
3430 * in an appropriate manner. In regular VNC, all the
3431 * TLS options get mapped into VNC_AUTH_VENCRYPT
3432 * sub-auth types.
f9148c8a
DB
3433 *
3434 * In websockets, the https:// protocol already provides
3435 * TLS support, so there is no need to make use of the
3436 * VeNCrypt extension. Furthermore, websockets browser
3437 * clients could not use VeNCrypt even if they wanted to,
3438 * as they cannot control when the TLS handshake takes
3439 * place. Thus there is no option but to rely on https://,
3440 * meaning combinations 4->6 and 7->9 will be mapped to
3441 * VNC auth schemes in the same way as combos 1->3.
3442 *
3443 * Regardless of fact that we have a different mapping to
3444 * VNC auth mechs for plain VNC vs websockets VNC, the end
3445 * result has the same security characteristics.
0dd72e15 3446 */
eda24e18
DB
3447 if (websocket || !tlscreds) {
3448 if (password) {
0dd72e15 3449 VNC_DEBUG("Initializing VNC server with password auth\n");
eda24e18
DB
3450 *auth = VNC_AUTH_VNC;
3451 } else if (sasl) {
3452 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3453 *auth = VNC_AUTH_SASL;
f9148c8a 3454 } else {
eda24e18
DB
3455 VNC_DEBUG("Initializing VNC server with no auth\n");
3456 *auth = VNC_AUTH_NONE;
f9148c8a 3457 }
eda24e18
DB
3458 *subauth = VNC_AUTH_INVALID;
3459 } else {
3460 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3461 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3462 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3463 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3464
3465 if (!is_x509 && !is_anon) {
3466 error_setg(errp,
3467 "Unsupported TLS cred type %s",
3468 object_get_typename(OBJECT(tlscreds)));
3469 return -1;
3470 }
3471 *auth = VNC_AUTH_VENCRYPT;
3472 if (password) {
3473 if (is_x509) {
3474 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3475 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3476 } else {
3477 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3478 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3479 }
3480
3481 } else if (sasl) {
3482 if (is_x509) {
0dd72e15 3483 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
eda24e18 3484 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3e305e4a 3485 } else {
eda24e18
DB
3486 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3487 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
0dd72e15
DB
3488 }
3489 } else {
eda24e18 3490 if (is_x509) {
0dd72e15 3491 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
eda24e18 3492 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3e305e4a 3493 } else {
eda24e18
DB
3494 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3495 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
0dd72e15 3496 }
f9148c8a 3497 }
0dd72e15 3498 }
3e305e4a
DB
3499 return 0;
3500}
3501
3502
3503/*
3504 * Handle back compat with old CLI syntax by creating some
3505 * suitable QCryptoTLSCreds objects
3506 */
3507static QCryptoTLSCreds *
3508vnc_display_create_creds(bool x509,
3509 bool x509verify,
3510 const char *dir,
3511 const char *id,
3512 Error **errp)
3513{
3514 gchar *credsid = g_strdup_printf("tlsvnc%s", id);
3515 Object *parent = object_get_objects_root();
3516 Object *creds;
3517 Error *err = NULL;
3518
3519 if (x509) {
3520 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
3521 parent,
3522 credsid,
3523 &err,
3524 "endpoint", "server",
3525 "dir", dir,
3526 "verify-peer", x509verify ? "yes" : "no",
3527 NULL);
3528 } else {
3529 creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
3530 parent,
3531 credsid,
3532 &err,
3533 "endpoint", "server",
3534 NULL);
3535 }
3536
3537 g_free(credsid);
3538
3539 if (err) {
3540 error_propagate(errp, err);
3541 return NULL;
3542 }
3543
3544 return QCRYPTO_TLS_CREDS(creds);
0dd72e15
DB
3545}
3546
3e305e4a 3547
275e0d61
DB
3548static int vnc_display_get_address(const char *addrstr,
3549 bool websocket,
e5766eb4 3550 bool reverse,
275e0d61
DB
3551 int displaynum,
3552 int to,
3553 bool has_ipv4,
3554 bool has_ipv6,
3555 bool ipv4,
3556 bool ipv6,
bd269ebc 3557 SocketAddress **retaddr,
275e0d61
DB
3558 Error **errp)
3559{
3560 int ret = -1;
bd269ebc 3561 SocketAddress *addr = NULL;
275e0d61 3562
bd269ebc 3563 addr = g_new0(SocketAddress, 1);
275e0d61
DB
3564
3565 if (strncmp(addrstr, "unix:", 5) == 0) {
bd269ebc
MA
3566 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3567 addr->u.q_unix.path = g_strdup(addrstr + 5);
275e0d61
DB
3568
3569 if (websocket) {
3570 error_setg(errp, "UNIX sockets not supported with websock");
3571 goto cleanup;
3572 }
3573
3574 if (to) {
3575 error_setg(errp, "Port range not support with UNIX socket");
3576 goto cleanup;
3577 }
3578 ret = 0;
3579 } else {
3580 const char *port;
3581 size_t hostlen;
3582 unsigned long long baseport = 0;
3583 InetSocketAddress *inet;
3584
3585 port = strrchr(addrstr, ':');
3586 if (!port) {
3587 if (websocket) {
3588 hostlen = 0;
3589 port = addrstr;
3590 } else {
3591 error_setg(errp, "no vnc port specified");
3592 goto cleanup;
3593 }
3594 } else {
3595 hostlen = port - addrstr;
3596 port++;
3597 if (*port == '\0') {
3598 error_setg(errp, "vnc port cannot be empty");
3599 goto cleanup;
3600 }
3601 }
3602
bd269ebc
MA
3603 addr->type = SOCKET_ADDRESS_TYPE_INET;
3604 inet = &addr->u.inet;
275e0d61
DB
3605 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3606 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3607 } else {
3608 inet->host = g_strndup(addrstr, hostlen);
3609 }
3610 /* plain VNC port is just an offset, for websocket
3611 * port is absolute */
3612 if (websocket) {
3613 if (g_str_equal(addrstr, "") ||
3614 g_str_equal(addrstr, "on")) {
396f935a
DB
3615 if (displaynum == -1) {
3616 error_setg(errp, "explicit websocket port is required");
3617 goto cleanup;
3618 }
275e0d61
DB
3619 inet->port = g_strdup_printf(
3620 "%d", displaynum + 5700);
3621 if (to) {
3622 inet->has_to = true;
3623 inet->to = to + 5700;
3624 }
3625 } else {
3626 inet->port = g_strdup(port);
3627 }
3628 } else {
e5766eb4 3629 int offset = reverse ? 0 : 5900;
275e0d61
DB
3630 if (parse_uint_full(port, &baseport, 10) < 0) {
3631 error_setg(errp, "can't convert to a number: %s", port);
3632 goto cleanup;
3633 }
3634 if (baseport > 65535 ||
e5766eb4 3635 baseport + offset > 65535) {
275e0d61
DB
3636 error_setg(errp, "port %s out of range", port);
3637 goto cleanup;
3638 }
3639 inet->port = g_strdup_printf(
e5766eb4 3640 "%d", (int)baseport + offset);
275e0d61
DB
3641
3642 if (to) {
3643 inet->has_to = true;
e5766eb4 3644 inet->to = to + offset;
275e0d61
DB
3645 }
3646 }
3647
3648 inet->ipv4 = ipv4;
3649 inet->has_ipv4 = has_ipv4;
3650 inet->ipv6 = ipv6;
3651 inet->has_ipv6 = has_ipv6;
3652
3653 ret = baseport;
3654 }
3655
3656 *retaddr = addr;
3657
3658 cleanup:
3659 if (ret < 0) {
bd269ebc 3660 qapi_free_SocketAddress(addr);
275e0d61
DB
3661 }
3662 return ret;
3663}
3664
9f26f325
PMD
3665static void vnc_free_addresses(SocketAddress ***retsaddr,
3666 size_t *retnsaddr)
3667{
3668 size_t i;
3669
3670 for (i = 0; i < *retnsaddr; i++) {
3671 qapi_free_SocketAddress((*retsaddr)[i]);
3672 }
3673 g_free(*retsaddr);
3674
3675 *retsaddr = NULL;
3676 *retnsaddr = 0;
3677}
3678
275e0d61 3679static int vnc_display_get_addresses(QemuOpts *opts,
e5766eb4 3680 bool reverse,
bd269ebc 3681 SocketAddress ***retsaddr,
396f935a 3682 size_t *retnsaddr,
bd269ebc 3683 SocketAddress ***retwsaddr,
396f935a 3684 size_t *retnwsaddr,
275e0d61
DB
3685 Error **errp)
3686{
bd269ebc
MA
3687 SocketAddress *saddr = NULL;
3688 SocketAddress *wsaddr = NULL;
396f935a
DB
3689 QemuOptsIter addriter;
3690 const char *addr;
275e0d61
DB
3691 int to = qemu_opt_get_number(opts, "to", 0);
3692 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3693 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3694 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3695 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
396f935a
DB
3696 int displaynum = -1;
3697 int ret = -1;
275e0d61 3698
396f935a
DB
3699 *retsaddr = NULL;
3700 *retnsaddr = 0;
3701 *retwsaddr = NULL;
3702 *retnwsaddr = 0;
275e0d61 3703
396f935a
DB
3704 addr = qemu_opt_get(opts, "vnc");
3705 if (addr == NULL || g_str_equal(addr, "none")) {
3706 ret = 0;
3707 goto cleanup;
3708 }
3709 if (qemu_opt_get(opts, "websocket") &&
275e0d61
DB
3710 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3711 error_setg(errp,
3712 "SHA1 hash support is required for websockets");
396f935a
DB
3713 goto cleanup;
3714 }
3715
3716 qemu_opt_iter_init(&addriter, opts, "vnc");
3717 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3718 int rv;
e5766eb4 3719 rv = vnc_display_get_address(addr, false, reverse, 0, to,
396f935a
DB
3720 has_ipv4, has_ipv6,
3721 ipv4, ipv6,
3722 &saddr, errp);
3723 if (rv < 0) {
3724 goto cleanup;
3725 }
3726 /* Historical compat - first listen address can be used
3727 * to set the default websocket port
3728 */
3729 if (displaynum == -1) {
3730 displaynum = rv;
3731 }
bd269ebc 3732 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
396f935a 3733 (*retsaddr)[(*retnsaddr)++] = saddr;
275e0d61
DB
3734 }
3735
396f935a
DB
3736 /* If we had multiple primary displays, we don't do defaults
3737 * for websocket, and require explicit config instead. */
3738 if (*retnsaddr > 1) {
3739 displaynum = -1;
275e0d61 3740 }
396f935a
DB
3741
3742 qemu_opt_iter_init(&addriter, opts, "websocket");
3743 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
e5766eb4 3744 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
275e0d61
DB
3745 has_ipv4, has_ipv6,
3746 ipv4, ipv6,
3747 &wsaddr, errp) < 0) {
396f935a 3748 goto cleanup;
275e0d61 3749 }
396f935a
DB
3750
3751 /* Historical compat - if only a single listen address was
3752 * provided, then this is used to set the default listen
3753 * address for websocket too
3754 */
3755 if (*retnsaddr == 1 &&
bd269ebc
MA
3756 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3757 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3758 g_str_equal(wsaddr->u.inet.host, "") &&
3759 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3760 g_free(wsaddr->u.inet.host);
3761 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
275e0d61 3762 }
396f935a 3763
bd269ebc 3764 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
396f935a 3765 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
275e0d61 3766 }
275e0d61 3767
396f935a
DB
3768 ret = 0;
3769 cleanup:
3770 if (ret < 0) {
9f26f325
PMD
3771 vnc_free_addresses(retsaddr, retnsaddr);
3772 vnc_free_addresses(retwsaddr, retnwsaddr);
396f935a
DB
3773 }
3774 return ret;
275e0d61
DB
3775}
3776
8bd22f47 3777static int vnc_display_connect(VncDisplay *vd,
bd269ebc 3778 SocketAddress **saddr,
396f935a 3779 size_t nsaddr,
bd269ebc 3780 SocketAddress **wsaddr,
396f935a 3781 size_t nwsaddr,
8bd22f47
DB
3782 Error **errp)
3783{
3784 /* connect to viewer */
3785 QIOChannelSocket *sioc = NULL;
396f935a 3786 if (nwsaddr != 0) {
8bd22f47
DB
3787 error_setg(errp, "Cannot use websockets in reverse mode");
3788 return -1;
3789 }
396f935a
DB
3790 if (nsaddr != 1) {
3791 error_setg(errp, "Expected a single address in reverse mode");
3792 return -1;
3793 }
bd269ebc
MA
3794 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
3795 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
8bd22f47
DB
3796 sioc = qio_channel_socket_new();
3797 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
396f935a 3798 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
8bd22f47
DB
3799 return -1;
3800 }
3801 vnc_connect(vd, sioc, false, false);
3802 object_unref(OBJECT(sioc));
3803 return 0;
3804}
3805
3806
8bd22f47 3807static int vnc_display_listen(VncDisplay *vd,
bd269ebc 3808 SocketAddress **saddr,
396f935a 3809 size_t nsaddr,
bd269ebc 3810 SocketAddress **wsaddr,
396f935a 3811 size_t nwsaddr,
8bd22f47
DB
3812 Error **errp)
3813{
396f935a 3814 size_t i;
8bd22f47 3815
13e1d0e7
DB
3816 if (nsaddr) {
3817 vd->listener = qio_net_listener_new();
3818 qio_net_listener_set_name(vd->listener, "vnc-listen");
3819 for (i = 0; i < nsaddr; i++) {
3820 if (qio_net_listener_open_sync(vd->listener,
3821 saddr[i],
3822 errp) < 0) {
3823 return -1;
3824 }
396f935a 3825 }
13e1d0e7
DB
3826
3827 qio_net_listener_set_client_func(vd->listener,
3828 vnc_listen_io, vd, NULL);
8bd22f47 3829 }
13e1d0e7
DB
3830
3831 if (nwsaddr) {
3832 vd->wslistener = qio_net_listener_new();
3833 qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
3834 for (i = 0; i < nwsaddr; i++) {
3835 if (qio_net_listener_open_sync(vd->wslistener,
3836 wsaddr[i],
3837 errp) < 0) {
3838 return -1;
3839 }
396f935a 3840 }
13e1d0e7
DB
3841
3842 qio_net_listener_set_client_func(vd->wslistener,
3843 vnc_listen_io, vd, NULL);
8bd22f47
DB
3844 }
3845
3846 return 0;
3847}
3848
3849
4db14629 3850void vnc_display_open(const char *id, Error **errp)
71cab5ca 3851{
bf01c179 3852 VncDisplay *vd = vnc_display_find(id);
4db14629 3853 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
bd269ebc 3854 SocketAddress **saddr = NULL, **wsaddr = NULL;
396f935a 3855 size_t nsaddr, nwsaddr;
e2a11d9d 3856 const char *share, *device_id;
1d0d59fe 3857 QemuConsole *con;
a2c72de0
GA
3858 bool password = false;
3859 bool reverse = false;
3e305e4a 3860 const char *credid;
a2c72de0 3861 bool sasl = false;
d169f04b 3862#ifdef CONFIG_VNC_SASL
2f9606b3
AL
3863 int saslErr;
3864#endif
76655d6d 3865 int acl = 0;
3a0558b5 3866 int lock_key_sync = 1;
c5ce8333 3867 int key_delay_ms;
71cab5ca 3868
bf01c179 3869 if (!vd) {
2d55f0e8
PB
3870 error_setg(errp, "VNC display not active");
3871 return;
3872 }
bf01c179 3873 vnc_display_close(vd);
24236869 3874
4db14629
GH
3875 if (!opts) {
3876 return;
3877 }
274c3b52 3878
e5766eb4
GH
3879 reverse = qemu_opt_get_bool(opts, "reverse", false);
3880 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
396f935a 3881 &wsaddr, &nwsaddr, errp) < 0) {
e5560329 3882 goto fail;
e2a11d9d 3883 }
e5560329 3884
4db14629 3885 password = qemu_opt_get_bool(opts, "password", false);
800567a6
DB
3886 if (password) {
3887 if (fips_get_state()) {
3888 error_setg(errp,
3889 "VNC password auth disabled due to FIPS mode, "
3890 "consider using the VeNCrypt or SASL authentication "
3891 "methods as an alternative");
3892 goto fail;
3893 }
3894 if (!qcrypto_cipher_supports(
f844836d 3895 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
800567a6
DB
3896 error_setg(errp,
3897 "Cipher backend does not support DES RFB algorithm");
3898 goto fail;
3899 }
4db14629
GH
3900 }
3901
4db14629 3902 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
d3b0db6d 3903 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
4db14629 3904 sasl = qemu_opt_get_bool(opts, "sasl", false);
d169f04b
DB
3905#ifndef CONFIG_VNC_SASL
3906 if (sasl) {
3907 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
3908 goto fail;
3909 }
3910#endif /* CONFIG_VNC_SASL */
3e305e4a
DB
3911 credid = qemu_opt_get(opts, "tls-creds");
3912 if (credid) {
3913 Object *creds;
3914 if (qemu_opt_get(opts, "tls") ||
3915 qemu_opt_get(opts, "x509") ||
3916 qemu_opt_get(opts, "x509verify")) {
3917 error_setg(errp,
c62e90af 3918 "'tls-creds' parameter is mutually exclusive with "
3e305e4a 3919 "'tls', 'x509' and 'x509verify' parameters");
4db14629
GH
3920 goto fail;
3921 }
3e305e4a
DB
3922
3923 creds = object_resolve_path_component(
3924 object_get_objects_root(), credid);
3925 if (!creds) {
3926 error_setg(errp, "No TLS credentials with id '%s'",
3927 credid);
3928 goto fail;
3929 }
bf01c179 3930 vd->tlscreds = (QCryptoTLSCreds *)
3e305e4a
DB
3931 object_dynamic_cast(creds,
3932 TYPE_QCRYPTO_TLS_CREDS);
bf01c179 3933 if (!vd->tlscreds) {
3e305e4a
DB
3934 error_setg(errp, "Object with id '%s' is not TLS credentials",
3935 credid);
3936 goto fail;
3937 }
bf01c179 3938 object_ref(OBJECT(vd->tlscreds));
3e305e4a 3939
bf01c179 3940 if (vd->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
3e305e4a
DB
3941 error_setg(errp,
3942 "Expecting TLS credentials with a server endpoint");
3943 goto fail;
3944 }
3945 } else {
3946 const char *path;
3947 bool tls = false, x509 = false, x509verify = false;
3948 tls = qemu_opt_get_bool(opts, "tls", false);
3949 if (tls) {
3950 path = qemu_opt_get(opts, "x509");
3951
3952 if (path) {
3953 x509 = true;
3954 } else {
3955 path = qemu_opt_get(opts, "x509verify");
3956 if (path) {
3957 x509 = true;
3958 x509verify = true;
3959 }
3960 }
bf01c179 3961 vd->tlscreds = vnc_display_create_creds(x509,
3e305e4a
DB
3962 x509verify,
3963 path,
bf01c179 3964 vd->id,
3e305e4a 3965 errp);
bf01c179 3966 if (!vd->tlscreds) {
3e305e4a
DB
3967 goto fail;
3968 }
3969 }
4db14629 3970 }
4db14629 3971 acl = qemu_opt_get_bool(opts, "acl", false);
4db14629
GH
3972
3973 share = qemu_opt_get(opts, "share");
3974 if (share) {
3975 if (strcmp(share, "ignore") == 0) {
bf01c179 3976 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
4db14629 3977 } else if (strcmp(share, "allow-exclusive") == 0) {
bf01c179 3978 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4db14629 3979 } else if (strcmp(share, "force-shared") == 0) {
bf01c179 3980 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
4db14629
GH
3981 } else {
3982 error_setg(errp, "unknown vnc share= option");
3983 goto fail;
3984 }
3985 } else {
bf01c179 3986 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4db14629 3987 }
bf01c179 3988 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4db14629 3989
4db14629 3990#ifdef CONFIG_VNC_JPEG
bf01c179 3991 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
4db14629 3992#endif
bf01c179 3993 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
e22492d3
PL
3994 /* adaptive updates are only used with tight encoding and
3995 * if lossy updates are enabled so we can disable all the
3996 * calculations otherwise */
bf01c179
DB
3997 if (!vd->lossy) {
3998 vd->non_adaptive = true;
e22492d3
PL
3999 }
4000
3e305e4a 4001 if (acl) {
bf01c179
DB
4002 if (strcmp(vd->id, "default") == 0) {
4003 vd->tlsaclname = g_strdup("vnc.x509dname");
c8496408 4004 } else {
bf01c179 4005 vd->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vd->id);
c8496408 4006 }
bf01c179 4007 qemu_acl_init(vd->tlsaclname);
2cc45228 4008 }
76655d6d
AL
4009#ifdef CONFIG_VNC_SASL
4010 if (acl && sasl) {
c8496408
GH
4011 char *aclname;
4012
bf01c179 4013 if (strcmp(vd->id, "default") == 0) {
c8496408
GH
4014 aclname = g_strdup("vnc.username");
4015 } else {
bf01c179 4016 aclname = g_strdup_printf("vnc.%s.username", vd->id);
c8496408 4017 }
bf01c179 4018 vd->sasl.acl = qemu_acl_init(aclname);
c8496408 4019 g_free(aclname);
76655d6d
AL
4020 }
4021#endif
4022
eda24e18
DB
4023 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
4024 vd->tlscreds, password,
4025 sasl, false, errp) < 0) {
4026 goto fail;
4027 }
7364dbda 4028 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
eda24e18
DB
4029
4030 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
4031 vd->tlscreds, password,
4032 sasl, true, errp) < 0) {
3e305e4a
DB
4033 goto fail;
4034 }
7364dbda 4035 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
24236869 4036
2f9606b3
AL
4037#ifdef CONFIG_VNC_SASL
4038 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2d55f0e8
PB
4039 error_setg(errp, "Failed to initialize SASL auth: %s",
4040 sasl_errstring(saslErr, NULL, NULL));
1ce52c78 4041 goto fail;
2f9606b3
AL
4042 }
4043#endif
bf01c179 4044 vd->lock_key_sync = lock_key_sync;
a54f0d2b
PO
4045 if (lock_key_sync) {
4046 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
4047 }
4048 vd->ledstate = 0;
bf01c179 4049 vd->key_delay_ms = key_delay_ms;
2f9606b3 4050
1d0d59fe
GH
4051 device_id = qemu_opt_get(opts, "display");
4052 if (device_id) {
1d0d59fe 4053 int head = qemu_opt_get_number(opts, "head", 0);
f2c1d54c 4054 Error *err = NULL;
1d0d59fe 4055
f2c1d54c
GH
4056 con = qemu_console_lookup_by_device_name(device_id, head, &err);
4057 if (err) {
4058 error_propagate(errp, err);
1d0d59fe
GH
4059 goto fail;
4060 }
4061 } else {
4062 con = NULL;
4063 }
4064
bf01c179
DB
4065 if (con != vd->dcl.con) {
4066 unregister_displaychangelistener(&vd->dcl);
4067 vd->dcl.con = con;
4068 register_displaychangelistener(&vd->dcl);
1d0d59fe
GH
4069 }
4070
fa03cb7f
MAL
4071 if (saddr == NULL) {
4072 goto cleanup;
4073 }
4074
3aa3eea3 4075 if (reverse) {
396f935a 4076 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
007fcd3e
PB
4077 goto fail;
4078 }
9712ecaf 4079 } else {
396f935a 4080 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
e0d03b8c
DB
4081 goto fail;
4082 }
24236869 4083 }
e0d03b8c 4084
275e0d61 4085 if (qemu_opt_get(opts, "to")) {
bf01c179 4086 vnc_display_print_local_addr(vd);
33df7bf3
PB
4087 }
4088
396f935a 4089 cleanup:
9f26f325
PMD
4090 vnc_free_addresses(&saddr, &nsaddr);
4091 vnc_free_addresses(&wsaddr, &nwsaddr);
2d55f0e8 4092 return;
1ce52c78
PB
4093
4094fail:
4ee74fa7 4095 vnc_display_close(vd);
396f935a 4096 goto cleanup;
24236869 4097}
13661089 4098
14f7143e 4099void vnc_display_add_client(const char *id, int csock, bool skipauth)
13661089 4100{
bf01c179 4101 VncDisplay *vd = vnc_display_find(id);
04d2529d 4102 QIOChannelSocket *sioc;
13661089 4103
bf01c179 4104 if (!vd) {
d616ccc5
GH
4105 return;
4106 }
04d2529d
DB
4107
4108 sioc = qio_channel_socket_new_fd(csock, NULL);
4109 if (sioc) {
10bcfe58 4110 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
bf01c179 4111 vnc_connect(vd, sioc, skipauth, false);
04d2529d
DB
4112 object_unref(OBJECT(sioc));
4113 }
13661089 4114}
4db14629 4115
9634f4e3 4116static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
2779672f
GA
4117{
4118 int i = 2;
4119 char *id;
4120
4121 id = g_strdup("default");
4122 while (qemu_opts_find(olist, id)) {
4123 g_free(id);
4124 id = g_strdup_printf("vnc%d", i++);
4125 }
4126 qemu_opts_set_id(opts, id);
4127}
4128
70b94331 4129QemuOpts *vnc_parse(const char *str, Error **errp)
4db14629 4130{
4db14629 4131 QemuOptsList *olist = qemu_find_opts("vnc");
70b94331 4132 QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
81607cbf 4133 const char *id;
4db14629 4134
81607cbf
GA
4135 if (!opts) {
4136 return NULL;
4137 }
4138
4139 id = qemu_opts_id(opts);
4db14629
GH
4140 if (!id) {
4141 /* auto-assign id if not present */
2779672f 4142 vnc_auto_assign_id(olist, opts);
4db14629 4143 }
9634f4e3
GH
4144 return opts;
4145}
4146
28d0de7a 4147int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
9634f4e3
GH
4148{
4149 Error *local_err = NULL;
4150 char *id = (char *)qemu_opts_id(opts);
4db14629 4151
9634f4e3 4152 assert(id);
4db14629
GH
4153 vnc_display_init(id);
4154 vnc_display_open(id, &local_err);
4155 if (local_err != NULL) {
c29b77f9 4156 error_reportf_err(local_err, "Failed to start VNC server: ");
4db14629
GH
4157 exit(1);
4158 }
4159 return 0;
4160}
4161
4162static void vnc_register_config(void)
4163{
4164 qemu_add_opts(&qemu_vnc_opts);
4165}
34294e2f 4166opts_init(vnc_register_config);
This page took 1.726464 seconds and 4 git commands to generate.