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