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