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