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