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