]> git.proxmox.com Git - mirror_qemu.git/blame - ui/vnc.c
pci-ids: document modern virtio-pci ids in pci.h too
[mirror_qemu.git] / ui / vnc.c
CommitLineData
7d510b8c
FB
1/*
2 * QEMU VNC display driver
5fafdf24 3 *
7d510b8c
FB
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
19a490bf 6 * Copyright (C) 2009 Red Hat, Inc
5fafdf24 7 *
7d510b8c
FB
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
e16f4c87 27#include "qemu/osdep.h"
19a490bf 28#include "vnc.h"
bd023f95 29#include "vnc-jobs.h"
40066175 30#include "trace.h"
13d4ff07 31#include "hw/qdev-core.h"
9c17d615 32#include "sysemu/sysemu.h"
7b5fa0b5 33#include "sysemu/runstate.h"
d49b6836 34#include "qemu/error-report.h"
db725815 35#include "qemu/main-loop.h"
0b8fa32f 36#include "qemu/module.h"
922a01a0 37#include "qemu/option.h"
1de7afc9
PB
38#include "qemu/sockets.h"
39#include "qemu/timer.h"
b76806d4 40#include "authz/list.h"
4db14629 41#include "qemu/config-file.h"
5d75648b
MA
42#include "qapi/qapi-emit-events.h"
43#include "qapi/qapi-events-ui.h"
e688df6b 44#include "qapi/error.h"
9af23989 45#include "qapi/qapi-commands-ui.h"
8d447d10 46#include "ui/input.h"
8e9b0d24 47#include "crypto/hash.h"
3c52bf0c 48#include "crypto/tlscreds.h"
3e305e4a
DB
49#include "crypto/tlscredsanon.h"
50#include "crypto/tlscredsx509.h"
f7b2502c 51#include "crypto/random.h"
6c6840e9 52#include "crypto/secret_common.h"
3e305e4a 53#include "qom/object_interfaces.h"
f348b6d1 54#include "qemu/cutils.h"
653c9747 55#include "qemu/help_option.h"
57a6d6d5 56#include "io/dns-resolver.h"
756a98dd 57#include "monitor/monitor.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;
95f8510e 2168#ifdef CONFIG_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
e03b5686 2343#if HOST_BIG_ENDIAN
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 }
d307040b 2445 uint32_t dlen = abs(read_s32(data, 4));
28a76be8 2446 if (len == 8) {
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 2458 if (read_s32(data, 4) < 0) {
d307040b
MMC
2459 if (dlen < 4) {
2460 error_report("vnc: malformed payload (header less than 4 bytes)"
2461 " in extended clipboard pseudo-encoding.");
2462 vnc_client_error(vs);
2463 break;
2464 }
2465 vnc_client_cut_text_ext(vs, dlen, read_u32(data, 8), data + 12);
0bf41cab
GH
2466 break;
2467 }
2468 vnc_client_cut_text(vs, read_u32(data, 4), data + 8);
28a76be8 2469 break;
7b5fa0b5
DB
2470 case VNC_MSG_CLIENT_XVP:
2471 if (!(vs->features & VNC_FEATURE_XVP)) {
2472 error_report("vnc: xvp client message while disabled");
2473 vnc_client_error(vs);
2474 break;
2475 }
2476 if (len == 1) {
2477 return 4;
2478 }
2479 if (len == 4) {
2480 uint8_t version = read_u8(data, 2);
2481 uint8_t action = read_u8(data, 3);
2482
2483 if (version != 1) {
2484 error_report("vnc: xvp client message version %d != 1",
2485 version);
2486 vnc_client_error(vs);
2487 break;
2488 }
2489
2490 switch (action) {
2491 case VNC_XVP_ACTION_SHUTDOWN:
2492 qemu_system_powerdown_request();
2493 break;
2494 case VNC_XVP_ACTION_REBOOT:
2495 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2496 break;
2497 case VNC_XVP_ACTION_RESET:
2498 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
2499 break;
2500 default:
2501 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2502 break;
2503 }
2504 }
2505 break;
46a183da 2506 case VNC_MSG_CLIENT_QEMU:
9ca313aa
AL
2507 if (len == 1)
2508 return 2;
2509
2510 switch (read_u8(data, 1)) {
46a183da 2511 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
9ca313aa
AL
2512 if (len == 2)
2513 return 12;
2514
2515 ext_key_event(vs, read_u16(data, 2),
2516 read_u32(data, 4), read_u32(data, 8));
2517 break;
46a183da 2518 case VNC_MSG_CLIENT_QEMU_AUDIO:
429a8ed3 2519 if (len == 2)
2520 return 4;
2521
2522 switch (read_u16 (data, 2)) {
46a183da 2523 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
adc8fce8 2524 trace_vnc_msg_client_audio_enable(vs, vs->ioc);
429a8ed3 2525 audio_add(vs);
2526 break;
46a183da 2527 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
adc8fce8 2528 trace_vnc_msg_client_audio_disable(vs, vs->ioc);
429a8ed3 2529 audio_del(vs);
2530 break;
46a183da 2531 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
429a8ed3 2532 if (len == 4)
2533 return 10;
2534 switch (read_u8(data, 4)) {
85bc5852
KZ
2535 case 0: vs->as.fmt = AUDIO_FORMAT_U8; break;
2536 case 1: vs->as.fmt = AUDIO_FORMAT_S8; break;
2537 case 2: vs->as.fmt = AUDIO_FORMAT_U16; break;
2538 case 3: vs->as.fmt = AUDIO_FORMAT_S16; break;
2539 case 4: vs->as.fmt = AUDIO_FORMAT_U32; break;
2540 case 5: vs->as.fmt = AUDIO_FORMAT_S32; break;
429a8ed3 2541 default:
153130cd 2542 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
429a8ed3 2543 vnc_client_error(vs);
2544 break;
2545 }
2546 vs->as.nchannels = read_u8(data, 5);
2547 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
090fdc83 2548 VNC_DEBUG("Invalid audio channel count %d\n",
153130cd 2549 read_u8(data, 5));
429a8ed3 2550 vnc_client_error(vs);
2551 break;
2552 }
cf070658
DB
2553 freq = read_u32(data, 6);
2554 /* No official limit for protocol, but 48khz is a sensible
2555 * upper bound for trustworthy clients, and this limit
2556 * protects calculations involving 'vs->as.freq' later.
2557 */
2558 if (freq > 48000) {
2559 VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
2560 vnc_client_error(vs);
2561 break;
2562 }
2563 vs->as.freq = freq;
adc8fce8
DB
2564 trace_vnc_msg_client_audio_format(
2565 vs, vs->ioc, vs->as.fmt, vs->as.nchannels, vs->as.freq);
429a8ed3 2566 break;
2567 default:
153130cd 2568 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
429a8ed3 2569 vnc_client_error(vs);
2570 break;
2571 }
2572 break;
2573
9ca313aa 2574 default:
153130cd 2575 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
9ca313aa
AL
2576 vnc_client_error(vs);
2577 break;
2578 }
2579 break;
763deea7
GH
2580 case VNC_MSG_CLIENT_SET_DESKTOP_SIZE:
2581 {
2582 size_t size;
2583 uint8_t screens;
adc8fce8 2584 int w, h;
763deea7
GH
2585
2586 if (len < 8) {
2587 return 8;
2588 }
2589
2590 screens = read_u8(data, 6);
2591 size = 8 + screens * 16;
2592 if (len < size) {
2593 return size;
2594 }
adc8fce8
DB
2595 w = read_u16(data, 2);
2596 h = read_u16(data, 4);
763deea7 2597
adc8fce8 2598 trace_vnc_msg_client_set_desktop_size(vs, vs->ioc, w, h, screens);
763deea7
GH
2599 if (dpy_ui_info_supported(vs->vd->dcl.con)) {
2600 QemuUIInfo info;
2601 memset(&info, 0, sizeof(info));
adc8fce8
DB
2602 info.width = w;
2603 info.height = h;
ca19ef52 2604 dpy_set_ui_info(vs->vd->dcl.con, &info, false);
763deea7
GH
2605 vnc_desktop_resize_ext(vs, 4 /* Request forwarded */);
2606 } else {
2607 vnc_desktop_resize_ext(vs, 3 /* Invalid screen layout */);
2608 }
2609
2610 break;
2611 }
24236869 2612 default:
153130cd 2613 VNC_DEBUG("Msg: %d\n", data[0]);
28a76be8
AL
2614 vnc_client_error(vs);
2615 break;
24236869 2616 }
5fafdf24 2617
e2b72cb6 2618 vnc_update_throttle_offset(vs);
24236869
FB
2619 vnc_read_when(vs, protocol_client_msg, 1);
2620 return 0;
2621}
2622
60fe76f3 2623static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869 2624{
c35734b2 2625 char buf[1024];
8cf36489 2626 VncShareMode mode;
c35734b2 2627 int size;
24236869 2628
8cf36489
GH
2629 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2630 switch (vs->vd->share_policy) {
2631 case VNC_SHARE_POLICY_IGNORE:
2632 /*
2633 * Ignore the shared flag. Nothing to do here.
2634 *
2635 * Doesn't conform to the rfb spec but is traditional qemu
2636 * behavior, thus left here as option for compatibility
2637 * reasons.
2638 */
2639 break;
2640 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2641 /*
2642 * Policy: Allow clients ask for exclusive access.
2643 *
2644 * Implementation: When a client asks for exclusive access,
2645 * disconnect all others. Shared connects are allowed as long
2646 * as no exclusive connection exists.
2647 *
2648 * This is how the rfb spec suggests to handle the shared flag.
2649 */
2650 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2651 VncState *client;
2652 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2653 if (vs == client) {
2654 continue;
2655 }
2656 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2657 client->share_mode != VNC_SHARE_MODE_SHARED) {
2658 continue;
2659 }
2660 vnc_disconnect_start(client);
2661 }
2662 }
2663 if (mode == VNC_SHARE_MODE_SHARED) {
2664 if (vs->vd->num_exclusive > 0) {
2665 vnc_disconnect_start(vs);
2666 return 0;
2667 }
2668 }
2669 break;
2670 case VNC_SHARE_POLICY_FORCE_SHARED:
2671 /*
2672 * Policy: Shared connects only.
2673 * Implementation: Disallow clients asking for exclusive access.
2674 *
2675 * Useful for shared desktop sessions where you don't want
2676 * someone forgetting to say -shared when running the vnc
2677 * client disconnect everybody else.
2678 */
2679 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2680 vnc_disconnect_start(vs);
2681 return 0;
2682 }
2683 break;
2684 }
2685 vnc_set_share_mode(vs, mode);
2686
e5f34cdd
GH
2687 if (vs->vd->num_shared > vs->vd->connections_limit) {
2688 vnc_disconnect_start(vs);
2689 return 0;
2690 }
2691
4c956bd8
DB
2692 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
2693 pixman_image_get_width(vs->vd->server) >= 0);
2694 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
2695 pixman_image_get_height(vs->vd->server) >= 0);
bea60dd7
PL
2696 vs->client_width = pixman_image_get_width(vs->vd->server);
2697 vs->client_height = pixman_image_get_height(vs->vd->server);
5862d195
GH
2698 vnc_write_u16(vs, vs->client_width);
2699 vnc_write_u16(vs, vs->client_height);
24236869 2700
ca4cca4d 2701 pixel_format_message(vs);
24236869 2702
97efe4f9 2703 if (qemu_name) {
c35734b2 2704 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
97efe4f9
TH
2705 if (size > sizeof(buf)) {
2706 size = sizeof(buf);
2707 }
2708 } else {
c35734b2 2709 size = snprintf(buf, sizeof(buf), "QEMU");
97efe4f9 2710 }
c35734b2
TS
2711
2712 vnc_write_u32(vs, size);
2713 vnc_write(vs, buf, size);
24236869
FB
2714 vnc_flush(vs);
2715
4a80dba3 2716 vnc_client_cache_auth(vs);
fb6ba0d5 2717 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
4a80dba3 2718
24236869
FB
2719 vnc_read_when(vs, protocol_client_msg, 1);
2720
2721 return 0;
2722}
2723
5fb6c7a8
AL
2724void start_client_init(VncState *vs)
2725{
2726 vnc_read_when(vs, protocol_client_init, 1);
2727}
2728
4347e638
RH
2729static void authentication_failed(VncState *vs)
2730{
2731 vnc_write_u32(vs, 1); /* Reject auth */
2732 if (vs->minor >= 8) {
2733 static const char err[] = "Authentication failed";
2734 vnc_write_u32(vs, sizeof(err));
2735 vnc_write(vs, err, sizeof(err));
2736 }
2737 vnc_flush(vs);
2738 vnc_client_error(vs);
2739}
2740
83bee4b5
DB
2741static void
2742vnc_munge_des_rfb_key(unsigned char *key, size_t nkey)
2743{
2744 size_t i;
2745 for (i = 0; i < nkey; i++) {
2746 uint8_t r = key[i];
2747 r = (r & 0xf0) >> 4 | (r & 0x0f) << 4;
2748 r = (r & 0xcc) >> 2 | (r & 0x33) << 2;
2749 r = (r & 0xaa) >> 1 | (r & 0x55) << 1;
2750 key[i] = r;
2751 }
2752}
2753
60fe76f3 2754static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 2755{
60fe76f3 2756 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
800567a6 2757 size_t i, pwlen;
60fe76f3 2758 unsigned char key[8];
3c9405a0 2759 time_t now = time(NULL);
60928458 2760 QCryptoCipher *cipher = NULL;
800567a6 2761 Error *err = NULL;
70848515 2762
1cd20f8b 2763 if (!vs->vd->password) {
7364dbda 2764 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
6bffdf0f 2765 goto reject;
70848515 2766 }
3c9405a0 2767 if (vs->vd->expires < now) {
7364dbda 2768 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
3c9405a0
GH
2769 goto reject;
2770 }
70848515
TS
2771
2772 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2773
2774 /* Calculate the expected challenge response */
753b4053 2775 pwlen = strlen(vs->vd->password);
70848515 2776 for (i=0; i<sizeof(key); i++)
753b4053 2777 key[i] = i<pwlen ? vs->vd->password[i] : 0;
83bee4b5 2778 vnc_munge_des_rfb_key(key, sizeof(key));
800567a6
DB
2779
2780 cipher = qcrypto_cipher_new(
83bee4b5 2781 QCRYPTO_CIPHER_ALG_DES,
800567a6
DB
2782 QCRYPTO_CIPHER_MODE_ECB,
2783 key, G_N_ELEMENTS(key),
2784 &err);
2785 if (!cipher) {
7364dbda
DB
2786 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2787 error_get_pretty(err));
800567a6
DB
2788 error_free(err);
2789 goto reject;
2790 }
2791
a1695137 2792 if (qcrypto_cipher_encrypt(cipher,
800567a6
DB
2793 vs->challenge,
2794 response,
2795 VNC_AUTH_CHALLENGE_SIZE,
2796 &err) < 0) {
7364dbda
DB
2797 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2798 error_get_pretty(err));
800567a6
DB
2799 error_free(err);
2800 goto reject;
2801 }
70848515
TS
2802
2803 /* Compare expected vs actual challenge response */
2804 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
7364dbda 2805 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
6bffdf0f 2806 goto reject;
70848515 2807 } else {
7364dbda 2808 trace_vnc_auth_pass(vs, vs->auth);
28a76be8
AL
2809 vnc_write_u32(vs, 0); /* Accept auth */
2810 vnc_flush(vs);
70848515 2811
5fb6c7a8 2812 start_client_init(vs);
70848515 2813 }
60928458
GA
2814
2815 qcrypto_cipher_free(cipher);
70848515 2816 return 0;
6bffdf0f
GH
2817
2818reject:
4347e638 2819 authentication_failed(vs);
60928458 2820 qcrypto_cipher_free(cipher);
6bffdf0f 2821 return 0;
70848515
TS
2822}
2823
5fb6c7a8 2824void start_auth_vnc(VncState *vs)
70848515 2825{
f7b2502c
RH
2826 Error *err = NULL;
2827
2828 if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), &err)) {
2829 trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
2830 error_get_pretty(err));
2831 error_free(err);
2832 authentication_failed(vs);
2833 return;
2834 }
2835
70848515
TS
2836 /* Send client a 'random' challenge */
2837 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2838 vnc_flush(vs);
2839
2840 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
469b15c6
TS
2841}
2842
2843
60fe76f3 2844static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
2845{
2846 /* We only advertise 1 auth scheme at a time, so client
2847 * must pick the one we sent. Verify this */
7e7e2ebc 2848 if (data[0] != vs->auth) { /* Reject auth */
7364dbda 2849 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
4347e638 2850 authentication_failed(vs);
70848515 2851 } else { /* Accept requested auth */
7364dbda 2852 trace_vnc_auth_start(vs, vs->auth);
7e7e2ebc 2853 switch (vs->auth) {
70848515 2854 case VNC_AUTH_NONE:
a26c97ad
AZ
2855 if (vs->minor >= 8) {
2856 vnc_write_u32(vs, 0); /* Accept auth completion */
2857 vnc_flush(vs);
2858 }
7364dbda 2859 trace_vnc_auth_pass(vs, vs->auth);
5fb6c7a8 2860 start_client_init(vs);
70848515
TS
2861 break;
2862
2863 case VNC_AUTH_VNC:
5fb6c7a8
AL
2864 start_auth_vnc(vs);
2865 break;
70848515 2866
8d5d2d4c 2867 case VNC_AUTH_VENCRYPT:
5fb6c7a8
AL
2868 start_auth_vencrypt(vs);
2869 break;
8d5d2d4c 2870
2f9606b3
AL
2871#ifdef CONFIG_VNC_SASL
2872 case VNC_AUTH_SASL:
2f9606b3
AL
2873 start_auth_sasl(vs);
2874 break;
2875#endif /* CONFIG_VNC_SASL */
2876
70848515 2877 default: /* Should not be possible, but just in case */
7364dbda 2878 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
4347e638 2879 authentication_failed(vs);
70848515
TS
2880 }
2881 }
2882 return 0;
2883}
2884
60fe76f3 2885static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
2886{
2887 char local[13];
24236869
FB
2888
2889 memcpy(local, version, 12);
2890 local[12] = 0;
2891
70848515 2892 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
28a76be8
AL
2893 VNC_DEBUG("Malformed protocol version %s\n", local);
2894 vnc_client_error(vs);
2895 return 0;
24236869 2896 }
70848515
TS
2897 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2898 if (vs->major != 3 ||
28a76be8
AL
2899 (vs->minor != 3 &&
2900 vs->minor != 4 &&
2901 vs->minor != 5 &&
2902 vs->minor != 7 &&
2903 vs->minor != 8)) {
2904 VNC_DEBUG("Unsupported client version\n");
2905 vnc_write_u32(vs, VNC_AUTH_INVALID);
2906 vnc_flush(vs);
2907 vnc_client_error(vs);
2908 return 0;
70848515 2909 }
b0566f4f 2910 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
2911 * as equivalent to v3.3 by servers
2912 */
b0566f4f 2913 if (vs->minor == 4 || vs->minor == 5)
28a76be8 2914 vs->minor = 3;
70848515
TS
2915
2916 if (vs->minor == 3) {
7364dbda 2917 trace_vnc_auth_start(vs, vs->auth);
7e7e2ebc 2918 if (vs->auth == VNC_AUTH_NONE) {
7e7e2ebc 2919 vnc_write_u32(vs, vs->auth);
70848515 2920 vnc_flush(vs);
7364dbda 2921 trace_vnc_auth_pass(vs, vs->auth);
28a76be8 2922 start_client_init(vs);
7e7e2ebc 2923 } else if (vs->auth == VNC_AUTH_VNC) {
70848515 2924 VNC_DEBUG("Tell client VNC auth\n");
7e7e2ebc 2925 vnc_write_u32(vs, vs->auth);
70848515
TS
2926 vnc_flush(vs);
2927 start_auth_vnc(vs);
2928 } else {
7364dbda
DB
2929 trace_vnc_auth_fail(vs, vs->auth,
2930 "Unsupported auth method for v3.3", "");
70848515
TS
2931 vnc_write_u32(vs, VNC_AUTH_INVALID);
2932 vnc_flush(vs);
2933 vnc_client_error(vs);
2934 }
2935 } else {
28a76be8 2936 vnc_write_u8(vs, 1); /* num auth */
7e7e2ebc 2937 vnc_write_u8(vs, vs->auth);
28a76be8
AL
2938 vnc_read_when(vs, protocol_client_auth, 1);
2939 vnc_flush(vs);
70848515 2940 }
24236869
FB
2941
2942 return 0;
2943}
2944
999342a0
CC
2945static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2946{
2947 struct VncSurface *vs = &vd->guest;
2948
2949 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2950}
2951
7d964c9d
CC
2952void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2953{
2954 int i, j;
2955
2956 w = (x + w) / VNC_STAT_RECT;
2957 h = (y + h) / VNC_STAT_RECT;
2958 x /= VNC_STAT_RECT;
2959 y /= VNC_STAT_RECT;
2960
207f328a
CC
2961 for (j = y; j <= h; j++) {
2962 for (i = x; i <= w; i++) {
7d964c9d
CC
2963 vs->lossy_rect[j][i] = 1;
2964 }
2965 }
2966}
2967
2968static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2969{
2970 VncState *vs;
2971 int sty = y / VNC_STAT_RECT;
2972 int stx = x / VNC_STAT_RECT;
2973 int has_dirty = 0;
2974
5a3804db
MAL
2975 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2976 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
7d964c9d
CC
2977
2978 QTAILQ_FOREACH(vs, &vd->clients, next) {
bc2429b9 2979 int j;
7d964c9d
CC
2980
2981 /* kernel send buffers are full -> refresh later */
2982 if (vs->output.offset) {
2983 continue;
2984 }
2985
2986 if (!vs->lossy_rect[sty][stx]) {
2987 continue;
2988 }
207f328a 2989
7d964c9d
CC
2990 vs->lossy_rect[sty][stx] = 0;
2991 for (j = 0; j < VNC_STAT_RECT; ++j) {
b4c85ddc
PL
2992 bitmap_set(vs->dirty[y + j],
2993 x / VNC_DIRTY_PIXELS_PER_BIT,
2994 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
7d964c9d
CC
2995 }
2996 has_dirty++;
2997 }
207f328a 2998
7d964c9d
CC
2999 return has_dirty;
3000}
3001
3002static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
999342a0 3003{
eebe0b79
GH
3004 int width = MIN(pixman_image_get_width(vd->guest.fb),
3005 pixman_image_get_width(vd->server));
3006 int height = MIN(pixman_image_get_height(vd->guest.fb),
3007 pixman_image_get_height(vd->server));
999342a0
CC
3008 int x, y;
3009 struct timeval res;
7d964c9d 3010 int has_dirty = 0;
999342a0 3011
9f64916d
GH
3012 for (y = 0; y < height; y += VNC_STAT_RECT) {
3013 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
3014 VncRectStat *rect = vnc_stat_rect(vd, x, y);
3015
3016 rect->updated = false;
3017 }
3018 }
3019
ad620c29 3020 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
999342a0
CC
3021
3022 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
7d964c9d 3023 return has_dirty;
999342a0
CC
3024 }
3025 vd->guest.last_freq_check = *tv;
3026
9f64916d
GH
3027 for (y = 0; y < height; y += VNC_STAT_RECT) {
3028 for (x = 0; x < width; x += VNC_STAT_RECT) {
999342a0
CC
3029 VncRectStat *rect= vnc_stat_rect(vd, x, y);
3030 int count = ARRAY_SIZE(rect->times);
3031 struct timeval min, max;
3032
3033 if (!timerisset(&rect->times[count - 1])) {
3034 continue ;
3035 }
3036
3037 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 3038 qemu_timersub(tv, &max, &res);
999342a0
CC
3039
3040 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
3041 rect->freq = 0;
7d964c9d 3042 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
999342a0
CC
3043 memset(rect->times, 0, sizeof (rect->times));
3044 continue ;
3045 }
3046
3047 min = rect->times[rect->idx];
3048 max = rect->times[(rect->idx + count - 1) % count];
ad620c29 3049 qemu_timersub(&max, &min, &res);
999342a0
CC
3050
3051 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
3052 rect->freq /= count;
3053 rect->freq = 1. / rect->freq;
3054 }
3055 }
7d964c9d 3056 return has_dirty;
999342a0
CC
3057}
3058
3059double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
3060{
3061 int i, j;
3062 double total = 0;
3063 int num = 0;
3064
5a3804db
MAL
3065 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
3066 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
999342a0
CC
3067
3068 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
3069 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
3070 total += vnc_stat_rect(vs->vd, i, j)->freq;
3071 num++;
3072 }
3073 }
3074
3075 if (num) {
3076 return total / num;
3077 } else {
3078 return 0;
3079 }
3080}
3081
3082static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
3083{
3084 VncRectStat *rect;
3085
3086 rect = vnc_stat_rect(vd, x, y);
3087 if (rect->updated) {
3088 return ;
3089 }
3090 rect->times[rect->idx] = *tv;
3091 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
3092 rect->updated = true;
3093}
3094
1fc62412
SS
3095static int vnc_refresh_server_surface(VncDisplay *vd)
3096{
bea60dd7
PL
3097 int width = MIN(pixman_image_get_width(vd->guest.fb),
3098 pixman_image_get_width(vd->server));
3099 int height = MIN(pixman_image_get_height(vd->guest.fb),
3100 pixman_image_get_height(vd->server));
eb8934b0 3101 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
12b316d4 3102 uint8_t *guest_row0 = NULL, *server_row0;
41b4bef6 3103 VncState *vs;
1fc62412 3104 int has_dirty = 0;
9f64916d 3105 pixman_image_t *tmpbuf = NULL;
6c08964b
WJ
3106 unsigned long offset;
3107 int x;
3108 uint8_t *guest_ptr, *server_ptr;
1fc62412 3109
80e0c8c3 3110 struct timeval tv = { 0, 0 };
999342a0 3111
80e0c8c3
CC
3112 if (!vd->non_adaptive) {
3113 gettimeofday(&tv, NULL);
3114 has_dirty = vnc_update_stats(vd, &tv);
3115 }
999342a0 3116
6c08964b
WJ
3117 offset = find_next_bit((unsigned long *) &vd->guest.dirty,
3118 height * VNC_DIRTY_BPL(&vd->guest), 0);
3119 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
3120 /* no dirty bits in guest surface */
3121 return has_dirty;
3122 }
3123
1fc62412
SS
3124 /*
3125 * Walk through the guest dirty map.
3126 * Check and copy modified bits from guest to server surface.
3127 * Update server dirty map.
3128 */
bea60dd7 3129 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
eb8934b0
GH
3130 server_stride = guest_stride = guest_ll =
3131 pixman_image_get_stride(vd->server);
bea60dd7
PL
3132 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
3133 server_stride);
9f64916d
GH
3134 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3135 int width = pixman_image_get_width(vd->server);
3136 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
12b316d4 3137 } else {
eb8934b0
GH
3138 int guest_bpp =
3139 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
12b316d4
PL
3140 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
3141 guest_stride = pixman_image_get_stride(vd->guest.fb);
949ed4c2
PMD
3142 guest_ll = pixman_image_get_width(vd->guest.fb)
3143 * DIV_ROUND_UP(guest_bpp, 8);
12b316d4 3144 }
eb8934b0 3145 line_bytes = MIN(server_stride, guest_ll);
12b316d4 3146
12b316d4 3147 for (;;) {
12b316d4
PL
3148 y = offset / VNC_DIRTY_BPL(&vd->guest);
3149 x = offset % VNC_DIRTY_BPL(&vd->guest);
1fc62412 3150
12b316d4
PL
3151 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
3152
3153 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3154 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
3155 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
3156 } else {
3157 guest_ptr = guest_row0 + y * guest_stride;
3158 }
3159 guest_ptr += x * cmp_bytes;
3160
3161 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
3162 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
bea60dd7 3163 int _cmp_bytes = cmp_bytes;
12b316d4
PL
3164 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
3165 continue;
3166 }
eb8934b0
GH
3167 if ((x + 1) * cmp_bytes > line_bytes) {
3168 _cmp_bytes = line_bytes - x * cmp_bytes;
bea60dd7 3169 }
eb8934b0 3170 assert(_cmp_bytes >= 0);
bea60dd7 3171 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
12b316d4
PL
3172 continue;
3173 }
bea60dd7 3174 memcpy(server_ptr, guest_ptr, _cmp_bytes);
12b316d4
PL
3175 if (!vd->non_adaptive) {
3176 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
3177 y, &tv);
1fc62412 3178 }
12b316d4
PL
3179 QTAILQ_FOREACH(vs, &vd->clients, next) {
3180 set_bit(x, vs->dirty[y]);
3181 }
3182 has_dirty++;
1fc62412 3183 }
12b316d4
PL
3184
3185 y++;
6c08964b
WJ
3186 offset = find_next_bit((unsigned long *) &vd->guest.dirty,
3187 height * VNC_DIRTY_BPL(&vd->guest),
3188 y * VNC_DIRTY_BPL(&vd->guest));
3189 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
3190 /* no more dirty bits */
3191 break;
3192 }
1fc62412 3193 }
9f64916d 3194 qemu_pixman_image_unref(tmpbuf);
1fc62412
SS
3195 return has_dirty;
3196}
3197
0f7b2864 3198static void vnc_refresh(DisplayChangeListener *dcl)
703bc68f 3199{
0f7b2864 3200 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
41b4bef6
AS
3201 VncState *vs, *vn;
3202 int has_dirty, rects = 0;
703bc68f 3203
9d6b2070
C
3204 if (QTAILQ_EMPTY(&vd->clients)) {
3205 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
3206 return;
3207 }
3208
1d0d59fe 3209 graphic_hw_update(vd->dcl.con);
703bc68f 3210
bd023f95 3211 if (vnc_trylock_display(vd)) {
0f7b2864 3212 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
bd023f95
CC
3213 return;
3214 }
3215
1fc62412 3216 has_dirty = vnc_refresh_server_surface(vd);
bd023f95 3217 vnc_unlock_display(vd);
1fc62412 3218
41b4bef6 3219 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
6af998db 3220 rects += vnc_update_client(vs, has_dirty);
6185c578 3221 /* vs might be free()ed here */
703bc68f 3222 }
bd023f95 3223
2430ffe4 3224 if (has_dirty && rects) {
0f7b2864
GH
3225 vd->dcl.update_interval /= 2;
3226 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
3227 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3228 }
2430ffe4 3229 } else {
0f7b2864
GH
3230 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3231 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3232 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3233 }
703bc68f
SS
3234 }
3235}
3236
04d2529d 3237static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
2c8cf549 3238 bool skipauth, bool websocket)
3aa3eea3 3239{
fedf0d35 3240 VncState *vs = g_new0(VncState, 1);
90cd03a3 3241 bool first_client = QTAILQ_EMPTY(&vd->clients);
7d964c9d
CC
3242 int i;
3243
ad6374c4 3244 trace_vnc_client_connect(vs, sioc);
6bf21f3d
LQ
3245 vs->zrle = g_new0(VncZrle, 1);
3246 vs->tight = g_new0(VncTight, 1);
f31f9c10 3247 vs->magic = VNC_MAGIC;
04d2529d
DB
3248 vs->sioc = sioc;
3249 object_ref(OBJECT(vs->sioc));
3250 vs->ioc = QIO_CHANNEL(sioc);
3251 object_ref(OBJECT(vs->ioc));
d616ccc5 3252 vs->vd = vd;
7e7e2ebc 3253
04d2529d
DB
3254 buffer_init(&vs->input, "vnc-input/%p", sioc);
3255 buffer_init(&vs->output, "vnc-output/%p", sioc);
04d2529d 3256 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
543b9580 3257
6bf21f3d
LQ
3258 buffer_init(&vs->tight->tight, "vnc-tight/%p", sioc);
3259 buffer_init(&vs->tight->zlib, "vnc-tight-zlib/%p", sioc);
3260 buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc);
543b9580 3261#ifdef CONFIG_VNC_JPEG
6bf21f3d 3262 buffer_init(&vs->tight->jpeg, "vnc-tight-jpeg/%p", sioc);
543b9580 3263#endif
95f8510e 3264#ifdef CONFIG_PNG
6bf21f3d 3265 buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc);
543b9580 3266#endif
04d2529d 3267 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
6bf21f3d
LQ
3268 buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc);
3269 buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc);
3270 buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc);
543b9580 3271
7e7e2ebc 3272 if (skipauth) {
7d37435b
PB
3273 vs->auth = VNC_AUTH_NONE;
3274 vs->subauth = VNC_AUTH_INVALID;
7e7e2ebc 3275 } else {
f9148c8a
DB
3276 if (websocket) {
3277 vs->auth = vd->ws_auth;
3278 vs->subauth = VNC_AUTH_INVALID;
3279 } else {
3280 vs->auth = vd->auth;
3281 vs->subauth = vd->subauth;
3282 }
7e7e2ebc 3283 }
04d2529d
DB
3284 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3285 sioc, websocket, vs->auth, vs->subauth);
7e7e2ebc 3286
7267c094 3287 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
7d964c9d 3288 for (i = 0; i < VNC_STAT_ROWS; ++i) {
fedf0d35 3289 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
7d964c9d 3290 }
753b4053 3291
04d2529d 3292 VNC_DEBUG("New client on socket %p\n", vs->sioc);
0f7b2864 3293 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
04d2529d 3294 qio_channel_set_blocking(vs->ioc, false, NULL);
a75d6f07
BC
3295 if (vs->ioc_tag) {
3296 g_source_remove(vs->ioc_tag);
3297 }
7536ee4b
TH
3298 if (websocket) {
3299 vs->websocket = 1;
38e5756a 3300 if (vd->tlscreds) {
04d2529d 3301 vs->ioc_tag = qio_channel_add_watch(
2ddafce7
DH
3302 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3303 vncws_tls_handshake_io, vs, NULL);
3e305e4a 3304 } else {
04d2529d 3305 vs->ioc_tag = qio_channel_add_watch(
2ddafce7
DH
3306 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3307 vncws_handshake_io, vs, NULL);
0057a0d5 3308 }
04d2529d
DB
3309 } else {
3310 vs->ioc_tag = qio_channel_add_watch(
2ddafce7
DH
3311 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3312 vnc_client_io, vs, NULL);
7536ee4b 3313 }
753b4053 3314
4a80dba3 3315 vnc_client_cache_addr(vs);
fb6ba0d5 3316 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
8cf36489 3317 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
4a80dba3 3318
753b4053
AL
3319 vs->last_x = -1;
3320 vs->last_y = -1;
3321
3322 vs->as.freq = 44100;
3323 vs->as.nchannels = 2;
85bc5852 3324 vs->as.fmt = AUDIO_FORMAT_S16;
753b4053
AL
3325 vs->as.endianness = 0;
3326
bd023f95 3327 qemu_mutex_init(&vs->output_mutex);
175b2a6e 3328 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
bd023f95 3329
e5f34cdd 3330 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
c7628bff
GH
3331 if (first_client) {
3332 vnc_update_server_surface(vd);
3333 }
1fc62412 3334
1d0d59fe 3335 graphic_hw_update(vd->dcl.con);
1fc62412 3336
90cd03a3 3337 if (!vs->websocket) {
dbee9897 3338 vnc_start_protocol(vs);
90cd03a3
DB
3339 }
3340
3341 if (vd->num_connecting > vd->connections_limit) {
3342 QTAILQ_FOREACH(vs, &vd->clients, next) {
3343 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3344 vnc_disconnect_start(vs);
3345 return;
3346 }
3347 }
3348 }
3349}
3350
dbee9897 3351void vnc_start_protocol(VncState *vs)
90cd03a3 3352{
3aa3eea3
AZ
3353 vnc_write(vs, "RFB 003.008\n", 12);
3354 vnc_flush(vs);
3355 vnc_read_when(vs, protocol_version, 12);
753b4053 3356
37c34d9d
AL
3357 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3358 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3aa3eea3
AZ
3359}
3360
13e1d0e7
DB
3361static void vnc_listen_io(QIONetListener *listener,
3362 QIOChannelSocket *cioc,
3363 void *opaque)
24236869 3364{
bf01c179 3365 VncDisplay *vd = opaque;
13e1d0e7 3366 bool isWebsock = listener == vd->wslistener;
7536ee4b 3367
13e1d0e7
DB
3368 qio_channel_set_name(QIO_CHANNEL(cioc),
3369 isWebsock ? "vnc-ws-server" : "vnc-server");
3370 qio_channel_set_delay(QIO_CHANNEL(cioc), false);
3371 vnc_connect(vd, cioc, false, isWebsock);
7536ee4b 3372}
7536ee4b 3373
7c20b4a3 3374static const DisplayChangeListenerOps dcl_ops = {
34da30af
BH
3375 .dpy_name = "vnc",
3376 .dpy_refresh = vnc_refresh,
34da30af
BH
3377 .dpy_gfx_update = vnc_dpy_update,
3378 .dpy_gfx_switch = vnc_dpy_switch,
3379 .dpy_gfx_check_format = qemu_pixman_check_format,
3380 .dpy_mouse_set = vnc_mouse_set,
3381 .dpy_cursor_define = vnc_dpy_cursor_define,
7c20b4a3
GH
3382};
3383
ab4f931e 3384void vnc_display_init(const char *id, Error **errp)
24236869 3385{
bf01c179 3386 VncDisplay *vd;
4db14629
GH
3387
3388 if (vnc_display_find(id) != NULL) {
3389 return;
3390 }
bf01c179 3391 vd = g_malloc0(sizeof(*vd));
24236869 3392
bf01c179
DB
3393 vd->id = strdup(id);
3394 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
24236869 3395
bf01c179
DB
3396 QTAILQ_INIT(&vd->clients);
3397 vd->expires = TIME_MAX;
24236869 3398
40066175
GH
3399 if (keyboard_layout) {
3400 trace_vnc_key_map_init(keyboard_layout);
ab4f931e
FL
3401 vd->kbd_layout = init_keyboard_layout(name2keysym,
3402 keyboard_layout, errp);
40066175 3403 } else {
ab4f931e 3404 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us", errp);
40066175 3405 }
24236869 3406
bf01c179 3407 if (!vd->kbd_layout) {
ab4f931e 3408 return;
bf01c179 3409 }
24236869 3410
bf01c179
DB
3411 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3412 vd->connections_limit = 32;
12e29b16 3413
bf01c179 3414 qemu_mutex_init(&vd->mutex);
bd023f95 3415 vnc_start_worker_thread();
bd023f95 3416
bf01c179
DB
3417 vd->dcl.ops = &dcl_ops;
3418 register_displaychangelistener(&vd->dcl);
c2f2ba49 3419 vd->kbd = qkbd_state_init(vd->dcl.con);
71cab5ca
TS
3420}
3421
6f43024c 3422
bf01c179 3423static void vnc_display_close(VncDisplay *vd)
71cab5ca 3424{
bf01c179 3425 if (!vd) {
452b4d88 3426 return;
bf01c179
DB
3427 }
3428 vd->is_unix = false;
13e1d0e7
DB
3429
3430 if (vd->listener) {
3431 qio_net_listener_disconnect(vd->listener);
3432 object_unref(OBJECT(vd->listener));
71cab5ca 3433 }
13e1d0e7 3434 vd->listener = NULL;
4ee74fa7 3435
13e1d0e7
DB
3436 if (vd->wslistener) {
3437 qio_net_listener_disconnect(vd->wslistener);
3438 object_unref(OBJECT(vd->wslistener));
7536ee4b 3439 }
13e1d0e7 3440 vd->wslistener = NULL;
4ee74fa7 3441
bf01c179
DB
3442 vd->auth = VNC_AUTH_INVALID;
3443 vd->subauth = VNC_AUTH_INVALID;
3444 if (vd->tlscreds) {
521534df 3445 object_unref(OBJECT(vd->tlscreds));
bf01c179 3446 vd->tlscreds = NULL;
3e305e4a 3447 }
b76806d4
DB
3448 if (vd->tlsauthz) {
3449 object_unparent(OBJECT(vd->tlsauthz));
3450 vd->tlsauthz = NULL;
3451 }
3452 g_free(vd->tlsauthzid);
3453 vd->tlsauthzid = NULL;
a54f0d2b
PO
3454 if (vd->lock_key_sync) {
3455 qemu_remove_led_event_handler(vd->led);
2dc120be 3456 vd->led = NULL;
a54f0d2b 3457 }
b76806d4
DB
3458#ifdef CONFIG_VNC_SASL
3459 if (vd->sasl.authz) {
3460 object_unparent(OBJECT(vd->sasl.authz));
3461 vd->sasl.authz = NULL;
3462 }
3463 g_free(vd->sasl.authzid);
3464 vd->sasl.authzid = NULL;
3465#endif
70848515
TS
3466}
3467
14f7143e 3468int vnc_display_password(const char *id, const char *password)
70848515 3469{
bf01c179 3470 VncDisplay *vd = vnc_display_find(id);
70848515 3471
bf01c179 3472 if (!vd) {
a6aa9d3e 3473 return -EINVAL;
7ef92331 3474 }
bf01c179 3475 if (vd->auth == VNC_AUTH_NONE) {
cf864569 3476 error_printf_unless_qmp("If you want use passwords please enable "
7ea7d36e 3477 "password auth using '-vnc ${dpy},password'.\n");
cf864569 3478 return -EINVAL;
1cd20f8b
AL
3479 }
3480
bf01c179
DB
3481 g_free(vd->password);
3482 vd->password = g_strdup(password);
a6aa9d3e
LC
3483
3484 return 0;
71cab5ca
TS
3485}
3486
14f7143e 3487int vnc_display_pw_expire(const char *id, time_t expires)
3c9405a0 3488{
bf01c179 3489 VncDisplay *vd = vnc_display_find(id);
3c9405a0 3490
bf01c179 3491 if (!vd) {
1643f2b2
GH
3492 return -EINVAL;
3493 }
3494
bf01c179 3495 vd->expires = expires;
3c9405a0
GH
3496 return 0;
3497}
3498
bf01c179 3499static void vnc_display_print_local_addr(VncDisplay *vd)
f92f8afe 3500{
bd269ebc 3501 SocketAddress *addr;
d616ccc5 3502
13e1d0e7 3503 if (!vd->listener || !vd->listener->nsioc) {
4ee74fa7
DB
3504 return;
3505 }
3506
b94b3c02 3507 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], NULL);
04d2529d 3508 if (!addr) {
33df7bf3 3509 return;
04d2529d
DB
3510 }
3511
bd269ebc
MA
3512 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3513 qapi_free_SocketAddress(addr);
33df7bf3 3514 return;
04d2529d 3515 }
33df7bf3 3516 error_printf_unless_qmp("VNC server running on %s:%s\n",
bd269ebc
MA
3517 addr->u.inet.host,
3518 addr->u.inet.port);
3519 qapi_free_SocketAddress(addr);
f92f8afe
AL
3520}
3521
4db14629
GH
3522static QemuOptsList qemu_vnc_opts = {
3523 .name = "vnc",
3524 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3525 .implied_opt_name = "vnc",
3526 .desc = {
3527 {
3528 .name = "vnc",
3529 .type = QEMU_OPT_STRING,
3530 },{
3531 .name = "websocket",
3532 .type = QEMU_OPT_STRING,
3533 },{
3e305e4a
DB
3534 .name = "tls-creds",
3535 .type = QEMU_OPT_STRING,
4db14629
GH
3536 },{
3537 .name = "share",
3538 .type = QEMU_OPT_STRING,
1d0d59fe
GH
3539 },{
3540 .name = "display",
3541 .type = QEMU_OPT_STRING,
3542 },{
3543 .name = "head",
3544 .type = QEMU_OPT_NUMBER,
e5f34cdd
GH
3545 },{
3546 .name = "connections",
3547 .type = QEMU_OPT_NUMBER,
88428b7a
GA
3548 },{
3549 .name = "to",
3550 .type = QEMU_OPT_NUMBER,
3551 },{
3552 .name = "ipv4",
3553 .type = QEMU_OPT_BOOL,
3554 },{
3555 .name = "ipv6",
3556 .type = QEMU_OPT_BOOL,
4db14629
GH
3557 },{
3558 .name = "password",
3559 .type = QEMU_OPT_BOOL,
6c6840e9
DB
3560 },{
3561 .name = "password-secret",
3562 .type = QEMU_OPT_STRING,
4db14629
GH
3563 },{
3564 .name = "reverse",
3565 .type = QEMU_OPT_BOOL,
3566 },{
3567 .name = "lock-key-sync",
3568 .type = QEMU_OPT_BOOL,
c5ce8333
GH
3569 },{
3570 .name = "key-delay-ms",
3571 .type = QEMU_OPT_NUMBER,
4db14629
GH
3572 },{
3573 .name = "sasl",
3574 .type = QEMU_OPT_BOOL,
55cf09a0
DB
3575 },{
3576 .name = "tls-authz",
3577 .type = QEMU_OPT_STRING,
3578 },{
3579 .name = "sasl-authz",
3580 .type = QEMU_OPT_STRING,
4db14629
GH
3581 },{
3582 .name = "lossy",
3583 .type = QEMU_OPT_BOOL,
3584 },{
3585 .name = "non-adaptive",
3586 .type = QEMU_OPT_BOOL,
f0b9f36d
KZ
3587 },{
3588 .name = "audiodev",
3589 .type = QEMU_OPT_STRING,
7b5fa0b5
DB
3590 },{
3591 .name = "power-control",
3592 .type = QEMU_OPT_BOOL,
4db14629
GH
3593 },
3594 { /* end of list */ }
3595 },
3596};
3597
0dd72e15 3598
3e305e4a 3599static int
eda24e18
DB
3600vnc_display_setup_auth(int *auth,
3601 int *subauth,
3602 QCryptoTLSCreds *tlscreds,
0dd72e15
DB
3603 bool password,
3604 bool sasl,
3e305e4a
DB
3605 bool websocket,
3606 Error **errp)
0dd72e15
DB
3607{
3608 /*
3609 * We have a choice of 3 authentication options
3610 *
3611 * 1. none
3612 * 2. vnc
3613 * 3. sasl
3614 *
3615 * The channel can be run in 2 modes
3616 *
3617 * 1. clear
3618 * 2. tls
3619 *
3620 * And TLS can use 2 types of credentials
3621 *
3622 * 1. anon
3623 * 2. x509
3624 *
3625 * We thus have 9 possible logical combinations
3626 *
3627 * 1. clear + none
3628 * 2. clear + vnc
3629 * 3. clear + sasl
3630 * 4. tls + anon + none
3631 * 5. tls + anon + vnc
3632 * 6. tls + anon + sasl
3633 * 7. tls + x509 + none
3634 * 8. tls + x509 + vnc
3635 * 9. tls + x509 + sasl
3636 *
3637 * These need to be mapped into the VNC auth schemes
3638 * in an appropriate manner. In regular VNC, all the
3639 * TLS options get mapped into VNC_AUTH_VENCRYPT
3640 * sub-auth types.
f9148c8a
DB
3641 *
3642 * In websockets, the https:// protocol already provides
3643 * TLS support, so there is no need to make use of the
3644 * VeNCrypt extension. Furthermore, websockets browser
3645 * clients could not use VeNCrypt even if they wanted to,
3646 * as they cannot control when the TLS handshake takes
3647 * place. Thus there is no option but to rely on https://,
3648 * meaning combinations 4->6 and 7->9 will be mapped to
3649 * VNC auth schemes in the same way as combos 1->3.
3650 *
3651 * Regardless of fact that we have a different mapping to
3652 * VNC auth mechs for plain VNC vs websockets VNC, the end
3653 * result has the same security characteristics.
0dd72e15 3654 */
eda24e18
DB
3655 if (websocket || !tlscreds) {
3656 if (password) {
0dd72e15 3657 VNC_DEBUG("Initializing VNC server with password auth\n");
eda24e18
DB
3658 *auth = VNC_AUTH_VNC;
3659 } else if (sasl) {
3660 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3661 *auth = VNC_AUTH_SASL;
f9148c8a 3662 } else {
eda24e18
DB
3663 VNC_DEBUG("Initializing VNC server with no auth\n");
3664 *auth = VNC_AUTH_NONE;
f9148c8a 3665 }
eda24e18
DB
3666 *subauth = VNC_AUTH_INVALID;
3667 } else {
3668 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3669 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3670 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3671 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3672
3673 if (!is_x509 && !is_anon) {
3674 error_setg(errp,
3675 "Unsupported TLS cred type %s",
3676 object_get_typename(OBJECT(tlscreds)));
3677 return -1;
3678 }
3679 *auth = VNC_AUTH_VENCRYPT;
3680 if (password) {
3681 if (is_x509) {
3682 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3683 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3684 } else {
3685 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3686 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3687 }
3688
3689 } else if (sasl) {
3690 if (is_x509) {
0dd72e15 3691 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
eda24e18 3692 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3e305e4a 3693 } else {
eda24e18
DB
3694 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3695 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
0dd72e15
DB
3696 }
3697 } else {
eda24e18 3698 if (is_x509) {
0dd72e15 3699 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
eda24e18 3700 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3e305e4a 3701 } else {
eda24e18
DB
3702 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3703 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
0dd72e15 3704 }
f9148c8a 3705 }
0dd72e15 3706 }
3e305e4a
DB
3707 return 0;
3708}
3709
3710
275e0d61
DB
3711static int vnc_display_get_address(const char *addrstr,
3712 bool websocket,
e5766eb4 3713 bool reverse,
275e0d61
DB
3714 int displaynum,
3715 int to,
3716 bool has_ipv4,
3717 bool has_ipv6,
3718 bool ipv4,
3719 bool ipv6,
bd269ebc 3720 SocketAddress **retaddr,
275e0d61
DB
3721 Error **errp)
3722{
3723 int ret = -1;
bd269ebc 3724 SocketAddress *addr = NULL;
275e0d61 3725
bd269ebc 3726 addr = g_new0(SocketAddress, 1);
275e0d61
DB
3727
3728 if (strncmp(addrstr, "unix:", 5) == 0) {
bd269ebc
MA
3729 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3730 addr->u.q_unix.path = g_strdup(addrstr + 5);
275e0d61
DB
3731
3732 if (websocket) {
3733 error_setg(errp, "UNIX sockets not supported with websock");
3734 goto cleanup;
3735 }
3736
3737 if (to) {
3738 error_setg(errp, "Port range not support with UNIX socket");
3739 goto cleanup;
3740 }
3741 ret = 0;
3742 } else {
3743 const char *port;
3744 size_t hostlen;
3745 unsigned long long baseport = 0;
3746 InetSocketAddress *inet;
3747
3748 port = strrchr(addrstr, ':');
3749 if (!port) {
3750 if (websocket) {
3751 hostlen = 0;
3752 port = addrstr;
3753 } else {
3754 error_setg(errp, "no vnc port specified");
3755 goto cleanup;
3756 }
3757 } else {
3758 hostlen = port - addrstr;
3759 port++;
3760 if (*port == '\0') {
3761 error_setg(errp, "vnc port cannot be empty");
3762 goto cleanup;
3763 }
3764 }
3765
bd269ebc
MA
3766 addr->type = SOCKET_ADDRESS_TYPE_INET;
3767 inet = &addr->u.inet;
275e0d61
DB
3768 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3769 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3770 } else {
3771 inet->host = g_strndup(addrstr, hostlen);
3772 }
3773 /* plain VNC port is just an offset, for websocket
3774 * port is absolute */
3775 if (websocket) {
3776 if (g_str_equal(addrstr, "") ||
3777 g_str_equal(addrstr, "on")) {
396f935a
DB
3778 if (displaynum == -1) {
3779 error_setg(errp, "explicit websocket port is required");
3780 goto cleanup;
3781 }
275e0d61
DB
3782 inet->port = g_strdup_printf(
3783 "%d", displaynum + 5700);
3784 if (to) {
3785 inet->has_to = true;
3786 inet->to = to + 5700;
3787 }
3788 } else {
3789 inet->port = g_strdup(port);
3790 }
3791 } else {
e5766eb4 3792 int offset = reverse ? 0 : 5900;
275e0d61
DB
3793 if (parse_uint_full(port, &baseport, 10) < 0) {
3794 error_setg(errp, "can't convert to a number: %s", port);
3795 goto cleanup;
3796 }
3797 if (baseport > 65535 ||
e5766eb4 3798 baseport + offset > 65535) {
275e0d61
DB
3799 error_setg(errp, "port %s out of range", port);
3800 goto cleanup;
3801 }
3802 inet->port = g_strdup_printf(
e5766eb4 3803 "%d", (int)baseport + offset);
275e0d61
DB
3804
3805 if (to) {
3806 inet->has_to = true;
e5766eb4 3807 inet->to = to + offset;
275e0d61
DB
3808 }
3809 }
3810
3811 inet->ipv4 = ipv4;
3812 inet->has_ipv4 = has_ipv4;
3813 inet->ipv6 = ipv6;
3814 inet->has_ipv6 = has_ipv6;
3815
3816 ret = baseport;
3817 }
3818
3819 *retaddr = addr;
3820
3821 cleanup:
3822 if (ret < 0) {
bd269ebc 3823 qapi_free_SocketAddress(addr);
275e0d61
DB
3824 }
3825 return ret;
3826}
3827
3828static int vnc_display_get_addresses(QemuOpts *opts,
e5766eb4 3829 bool reverse,
d708f99d
VSO
3830 SocketAddressList **saddr_list_ret,
3831 SocketAddressList **wsaddr_list_ret,
275e0d61
DB
3832 Error **errp)
3833{
bd269ebc
MA
3834 SocketAddress *saddr = NULL;
3835 SocketAddress *wsaddr = NULL;
d708f99d
VSO
3836 g_autoptr(SocketAddressList) saddr_list = NULL;
3837 SocketAddressList **saddr_tail = &saddr_list;
3838 SocketAddress *single_saddr = NULL;
3839 g_autoptr(SocketAddressList) wsaddr_list = NULL;
3840 SocketAddressList **wsaddr_tail = &wsaddr_list;
396f935a
DB
3841 QemuOptsIter addriter;
3842 const char *addr;
275e0d61
DB
3843 int to = qemu_opt_get_number(opts, "to", 0);
3844 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3845 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3846 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3847 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
396f935a 3848 int displaynum = -1;
275e0d61 3849
396f935a
DB
3850 addr = qemu_opt_get(opts, "vnc");
3851 if (addr == NULL || g_str_equal(addr, "none")) {
d708f99d 3852 return 0;
396f935a
DB
3853 }
3854 if (qemu_opt_get(opts, "websocket") &&
275e0d61
DB
3855 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3856 error_setg(errp,
3857 "SHA1 hash support is required for websockets");
d708f99d 3858 return -1;
396f935a
DB
3859 }
3860
3861 qemu_opt_iter_init(&addriter, opts, "vnc");
3862 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3863 int rv;
e5766eb4 3864 rv = vnc_display_get_address(addr, false, reverse, 0, to,
396f935a
DB
3865 has_ipv4, has_ipv6,
3866 ipv4, ipv6,
3867 &saddr, errp);
3868 if (rv < 0) {
d708f99d 3869 return -1;
396f935a
DB
3870 }
3871 /* Historical compat - first listen address can be used
3872 * to set the default websocket port
3873 */
3874 if (displaynum == -1) {
3875 displaynum = rv;
3876 }
d708f99d 3877 QAPI_LIST_APPEND(saddr_tail, saddr);
275e0d61
DB
3878 }
3879
d708f99d
VSO
3880 if (saddr_list && !saddr_list->next) {
3881 single_saddr = saddr_list->value;
3882 } else {
3883 /*
3884 * If we had multiple primary displays, we don't do defaults
3885 * for websocket, and require explicit config instead.
3886 */
396f935a 3887 displaynum = -1;
275e0d61 3888 }
396f935a
DB
3889
3890 qemu_opt_iter_init(&addriter, opts, "websocket");
3891 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
e5766eb4 3892 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
275e0d61
DB
3893 has_ipv4, has_ipv6,
3894 ipv4, ipv6,
3895 &wsaddr, errp) < 0) {
d708f99d 3896 return -1;
275e0d61 3897 }
396f935a
DB
3898
3899 /* Historical compat - if only a single listen address was
3900 * provided, then this is used to set the default listen
3901 * address for websocket too
3902 */
d708f99d
VSO
3903 if (single_saddr &&
3904 single_saddr->type == SOCKET_ADDRESS_TYPE_INET &&
bd269ebc
MA
3905 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3906 g_str_equal(wsaddr->u.inet.host, "") &&
d708f99d 3907 !g_str_equal(single_saddr->u.inet.host, "")) {
bd269ebc 3908 g_free(wsaddr->u.inet.host);
d708f99d 3909 wsaddr->u.inet.host = g_strdup(single_saddr->u.inet.host);
275e0d61 3910 }
396f935a 3911
d708f99d 3912 QAPI_LIST_APPEND(wsaddr_tail, wsaddr);
275e0d61 3913 }
275e0d61 3914
d708f99d
VSO
3915 *saddr_list_ret = g_steal_pointer(&saddr_list);
3916 *wsaddr_list_ret = g_steal_pointer(&wsaddr_list);
3917 return 0;
275e0d61
DB
3918}
3919
8bd22f47 3920static int vnc_display_connect(VncDisplay *vd,
d708f99d
VSO
3921 SocketAddressList *saddr_list,
3922 SocketAddressList *wsaddr_list,
8bd22f47
DB
3923 Error **errp)
3924{
3925 /* connect to viewer */
3926 QIOChannelSocket *sioc = NULL;
d708f99d 3927 if (wsaddr_list) {
8bd22f47
DB
3928 error_setg(errp, "Cannot use websockets in reverse mode");
3929 return -1;
3930 }
d708f99d 3931 if (!saddr_list || saddr_list->next) {
396f935a
DB
3932 error_setg(errp, "Expected a single address in reverse mode");
3933 return -1;
3934 }
bd269ebc 3935 /* TODO SOCKET_ADDRESS_TYPE_FD when fd has AF_UNIX */
d708f99d 3936 vd->is_unix = saddr_list->value->type == SOCKET_ADDRESS_TYPE_UNIX;
8bd22f47
DB
3937 sioc = qio_channel_socket_new();
3938 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
d708f99d 3939 if (qio_channel_socket_connect_sync(sioc, saddr_list->value, errp) < 0) {
5f8679fe 3940 object_unref(OBJECT(sioc));
8bd22f47
DB
3941 return -1;
3942 }
3943 vnc_connect(vd, sioc, false, false);
3944 object_unref(OBJECT(sioc));
3945 return 0;
3946}
3947
3948
8bd22f47 3949static int vnc_display_listen(VncDisplay *vd,
d708f99d
VSO
3950 SocketAddressList *saddr_list,
3951 SocketAddressList *wsaddr_list,
8bd22f47
DB
3952 Error **errp)
3953{
d708f99d 3954 SocketAddressList *el;
8bd22f47 3955
d708f99d 3956 if (saddr_list) {
13e1d0e7
DB
3957 vd->listener = qio_net_listener_new();
3958 qio_net_listener_set_name(vd->listener, "vnc-listen");
d708f99d 3959 for (el = saddr_list; el; el = el->next) {
13e1d0e7 3960 if (qio_net_listener_open_sync(vd->listener,
d708f99d 3961 el->value, 1,
13e1d0e7
DB
3962 errp) < 0) {
3963 return -1;
3964 }
396f935a 3965 }
13e1d0e7
DB
3966
3967 qio_net_listener_set_client_func(vd->listener,
3968 vnc_listen_io, vd, NULL);
8bd22f47 3969 }
13e1d0e7 3970
d708f99d 3971 if (wsaddr_list) {
13e1d0e7
DB
3972 vd->wslistener = qio_net_listener_new();
3973 qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
d708f99d 3974 for (el = wsaddr_list; el; el = el->next) {
13e1d0e7 3975 if (qio_net_listener_open_sync(vd->wslistener,
d708f99d 3976 el->value, 1,
13e1d0e7
DB
3977 errp) < 0) {
3978 return -1;
3979 }
396f935a 3980 }
13e1d0e7
DB
3981
3982 qio_net_listener_set_client_func(vd->wslistener,
3983 vnc_listen_io, vd, NULL);
8bd22f47
DB
3984 }
3985
3986 return 0;
3987}
3988
abea1946
VSO
3989bool vnc_display_update(DisplayUpdateOptionsVNC *arg, Error **errp)
3990{
3991 VncDisplay *vd = vnc_display_find(NULL);
3992
3993 if (!vd) {
3994 error_setg(errp, "Can not find vnc display");
3995 return false;
3996 }
3997
3998 if (arg->has_addresses) {
3999 if (vd->listener) {
4000 qio_net_listener_disconnect(vd->listener);
4001 object_unref(OBJECT(vd->listener));
4002 vd->listener = NULL;
4003 }
4004
4005 if (vnc_display_listen(vd, arg->addresses, NULL, errp) < 0) {
4006 return false;
4007 }
4008 }
4009
4010 return true;
4011}
8bd22f47 4012
4db14629 4013void vnc_display_open(const char *id, Error **errp)
71cab5ca 4014{
bf01c179 4015 VncDisplay *vd = vnc_display_find(id);
4db14629 4016 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
d708f99d
VSO
4017 g_autoptr(SocketAddressList) saddr_list = NULL;
4018 g_autoptr(SocketAddressList) wsaddr_list = NULL;
e2a11d9d 4019 const char *share, *device_id;
1d0d59fe 4020 QemuConsole *con;
a2c72de0
GA
4021 bool password = false;
4022 bool reverse = false;
3e305e4a 4023 const char *credid;
a2c72de0 4024 bool sasl = false;
55cf09a0
DB
4025 const char *tlsauthz;
4026 const char *saslauthz;
3a0558b5 4027 int lock_key_sync = 1;
c5ce8333 4028 int key_delay_ms;
f0b9f36d 4029 const char *audiodev;
6c6840e9 4030 const char *passwordSecret;
71cab5ca 4031
bf01c179 4032 if (!vd) {
2d55f0e8
PB
4033 error_setg(errp, "VNC display not active");
4034 return;
4035 }
bf01c179 4036 vnc_display_close(vd);
24236869 4037
4db14629
GH
4038 if (!opts) {
4039 return;
4040 }
274c3b52 4041
e5766eb4 4042 reverse = qemu_opt_get_bool(opts, "reverse", false);
d708f99d
VSO
4043 if (vnc_display_get_addresses(opts, reverse, &saddr_list, &wsaddr_list,
4044 errp) < 0) {
e5560329 4045 goto fail;
e2a11d9d 4046 }
e5560329 4047
6c6840e9
DB
4048
4049 passwordSecret = qemu_opt_get(opts, "password-secret");
4050 if (passwordSecret) {
4051 if (qemu_opt_get(opts, "password")) {
4052 error_setg(errp,
4053 "'password' flag is redundant with 'password-secret'");
4054 goto fail;
4055 }
4056 vd->password = qcrypto_secret_lookup_as_utf8(passwordSecret,
4057 errp);
4058 if (!vd->password) {
4059 goto fail;
4060 }
4061 password = true;
4062 } else {
4063 password = qemu_opt_get_bool(opts, "password", false);
4064 }
800567a6 4065 if (password) {
800567a6 4066 if (!qcrypto_cipher_supports(
83bee4b5 4067 QCRYPTO_CIPHER_ALG_DES, QCRYPTO_CIPHER_MODE_ECB)) {
800567a6 4068 error_setg(errp,
83bee4b5 4069 "Cipher backend does not support DES algorithm");
800567a6
DB
4070 goto fail;
4071 }
4db14629
GH
4072 }
4073
4db14629 4074 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
d3b0db6d 4075 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
4db14629 4076 sasl = qemu_opt_get_bool(opts, "sasl", false);
d169f04b
DB
4077#ifndef CONFIG_VNC_SASL
4078 if (sasl) {
4079 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
4080 goto fail;
4081 }
4082#endif /* CONFIG_VNC_SASL */
3e305e4a
DB
4083 credid = qemu_opt_get(opts, "tls-creds");
4084 if (credid) {
4085 Object *creds;
3e305e4a
DB
4086 creds = object_resolve_path_component(
4087 object_get_objects_root(), credid);
4088 if (!creds) {
4089 error_setg(errp, "No TLS credentials with id '%s'",
4090 credid);
4091 goto fail;
4092 }
bf01c179 4093 vd->tlscreds = (QCryptoTLSCreds *)
3e305e4a
DB
4094 object_dynamic_cast(creds,
4095 TYPE_QCRYPTO_TLS_CREDS);
bf01c179 4096 if (!vd->tlscreds) {
3e305e4a
DB
4097 error_setg(errp, "Object with id '%s' is not TLS credentials",
4098 credid);
4099 goto fail;
4100 }
bf01c179 4101 object_ref(OBJECT(vd->tlscreds));
3e305e4a 4102
3c52bf0c
PMD
4103 if (!qcrypto_tls_creds_check_endpoint(vd->tlscreds,
4104 QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
4105 errp)) {
3e305e4a
DB
4106 goto fail;
4107 }
4db14629 4108 }
55cf09a0 4109 tlsauthz = qemu_opt_get(opts, "tls-authz");
55cf09a0
DB
4110 if (tlsauthz && !vd->tlscreds) {
4111 error_setg(errp, "'tls-authz' provided but TLS is not enabled");
4112 goto fail;
4113 }
4114
4115 saslauthz = qemu_opt_get(opts, "sasl-authz");
55cf09a0
DB
4116 if (saslauthz && !sasl) {
4117 error_setg(errp, "'sasl-authz' provided but SASL auth is not enabled");
4118 goto fail;
4119 }
4db14629
GH
4120
4121 share = qemu_opt_get(opts, "share");
4122 if (share) {
4123 if (strcmp(share, "ignore") == 0) {
bf01c179 4124 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
4db14629 4125 } else if (strcmp(share, "allow-exclusive") == 0) {
bf01c179 4126 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4db14629 4127 } else if (strcmp(share, "force-shared") == 0) {
bf01c179 4128 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
4db14629
GH
4129 } else {
4130 error_setg(errp, "unknown vnc share= option");
4131 goto fail;
4132 }
4133 } else {
bf01c179 4134 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4db14629 4135 }
bf01c179 4136 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4db14629 4137
4db14629 4138#ifdef CONFIG_VNC_JPEG
bf01c179 4139 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
4db14629 4140#endif
bf01c179 4141 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
e22492d3
PL
4142 /* adaptive updates are only used with tight encoding and
4143 * if lossy updates are enabled so we can disable all the
4144 * calculations otherwise */
bf01c179
DB
4145 if (!vd->lossy) {
4146 vd->non_adaptive = true;
e22492d3
PL
4147 }
4148
7b5fa0b5
DB
4149 vd->power_control = qemu_opt_get_bool(opts, "power-control", false);
4150
55cf09a0
DB
4151 if (tlsauthz) {
4152 vd->tlsauthzid = g_strdup(tlsauthz);
2cc45228 4153 }
76655d6d 4154#ifdef CONFIG_VNC_SASL
55cf09a0
DB
4155 if (sasl) {
4156 if (saslauthz) {
4157 vd->sasl.authzid = g_strdup(saslauthz);
c8496408 4158 }
76655d6d
AL
4159 }
4160#endif
4161
eda24e18
DB
4162 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
4163 vd->tlscreds, password,
4164 sasl, false, errp) < 0) {
4165 goto fail;
4166 }
7364dbda 4167 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
eda24e18
DB
4168
4169 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
4170 vd->tlscreds, password,
4171 sasl, true, errp) < 0) {
3e305e4a
DB
4172 goto fail;
4173 }
7364dbda 4174 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
24236869 4175
2f9606b3 4176#ifdef CONFIG_VNC_SASL
b65310ab
PB
4177 if (sasl && !vnc_sasl_server_init(errp)) {
4178 goto fail;
2f9606b3
AL
4179 }
4180#endif
bf01c179 4181 vd->lock_key_sync = lock_key_sync;
a54f0d2b
PO
4182 if (lock_key_sync) {
4183 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
4184 }
4185 vd->ledstate = 0;
2f9606b3 4186
f0b9f36d
KZ
4187 audiodev = qemu_opt_get(opts, "audiodev");
4188 if (audiodev) {
4189 vd->audio_state = audio_state_by_name(audiodev);
4190 if (!vd->audio_state) {
4191 error_setg(errp, "Audiodev '%s' not found", audiodev);
4192 goto fail;
4193 }
4194 }
4195
1d0d59fe
GH
4196 device_id = qemu_opt_get(opts, "display");
4197 if (device_id) {
1d0d59fe 4198 int head = qemu_opt_get_number(opts, "head", 0);
f2c1d54c 4199 Error *err = NULL;
1d0d59fe 4200
f2c1d54c
GH
4201 con = qemu_console_lookup_by_device_name(device_id, head, &err);
4202 if (err) {
4203 error_propagate(errp, err);
1d0d59fe
GH
4204 goto fail;
4205 }
4206 } else {
4207 con = NULL;
4208 }
4209
bf01c179 4210 if (con != vd->dcl.con) {
c2f2ba49 4211 qkbd_state_free(vd->kbd);
bf01c179
DB
4212 unregister_displaychangelistener(&vd->dcl);
4213 vd->dcl.con = con;
4214 register_displaychangelistener(&vd->dcl);
c2f2ba49 4215 vd->kbd = qkbd_state_init(vd->dcl.con);
1d0d59fe 4216 }
c2f2ba49 4217 qkbd_state_set_delay(vd->kbd, key_delay_ms);
1d0d59fe 4218
d708f99d
VSO
4219 if (saddr_list == NULL) {
4220 return;
fa03cb7f
MAL
4221 }
4222
3aa3eea3 4223 if (reverse) {
d708f99d 4224 if (vnc_display_connect(vd, saddr_list, wsaddr_list, errp) < 0) {
007fcd3e
PB
4225 goto fail;
4226 }
9712ecaf 4227 } else {
d708f99d 4228 if (vnc_display_listen(vd, saddr_list, wsaddr_list, errp) < 0) {
e0d03b8c
DB
4229 goto fail;
4230 }
24236869 4231 }
e0d03b8c 4232
275e0d61 4233 if (qemu_opt_get(opts, "to")) {
bf01c179 4234 vnc_display_print_local_addr(vd);
33df7bf3
PB
4235 }
4236
d708f99d 4237 /* Success */
2d55f0e8 4238 return;
1ce52c78
PB
4239
4240fail:
4ee74fa7 4241 vnc_display_close(vd);
24236869 4242}
13661089 4243
14f7143e 4244void vnc_display_add_client(const char *id, int csock, bool skipauth)
13661089 4245{
bf01c179 4246 VncDisplay *vd = vnc_display_find(id);
04d2529d 4247 QIOChannelSocket *sioc;
13661089 4248
bf01c179 4249 if (!vd) {
d616ccc5
GH
4250 return;
4251 }
04d2529d
DB
4252
4253 sioc = qio_channel_socket_new_fd(csock, NULL);
4254 if (sioc) {
10bcfe58 4255 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
bf01c179 4256 vnc_connect(vd, sioc, skipauth, false);
04d2529d
DB
4257 object_unref(OBJECT(sioc));
4258 }
13661089 4259}
4db14629 4260
9634f4e3 4261static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
2779672f
GA
4262{
4263 int i = 2;
4264 char *id;
4265
4266 id = g_strdup("default");
4267 while (qemu_opts_find(olist, id)) {
4268 g_free(id);
4269 id = g_strdup_printf("vnc%d", i++);
4270 }
4271 qemu_opts_set_id(opts, id);
4272}
4273
653c9747 4274void vnc_parse(const char *str)
4db14629 4275{
4db14629 4276 QemuOptsList *olist = qemu_find_opts("vnc");
653c9747 4277 QemuOpts *opts = qemu_opts_parse_noisily(olist, str, !is_help_option(str));
81607cbf 4278 const char *id;
4db14629 4279
81607cbf 4280 if (!opts) {
653c9747 4281 exit(1);
81607cbf
GA
4282 }
4283
4284 id = qemu_opts_id(opts);
4db14629
GH
4285 if (!id) {
4286 /* auto-assign id if not present */
2779672f 4287 vnc_auto_assign_id(olist, opts);
4db14629 4288 }
9634f4e3
GH
4289}
4290
28d0de7a 4291int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
9634f4e3
GH
4292{
4293 Error *local_err = NULL;
4294 char *id = (char *)qemu_opts_id(opts);
4db14629 4295
9634f4e3 4296 assert(id);
ab4f931e
FL
4297 vnc_display_init(id, &local_err);
4298 if (local_err) {
612aea20
MA
4299 error_propagate(errp, local_err);
4300 return -1;
ab4f931e 4301 }
4db14629
GH
4302 vnc_display_open(id, &local_err);
4303 if (local_err != NULL) {
612aea20
MA
4304 error_propagate(errp, local_err);
4305 return -1;
4db14629
GH
4306 }
4307 return 0;
4308}
4309
4310static void vnc_register_config(void)
4311{
4312 qemu_add_opts(&qemu_vnc_opts);
4313}
34294e2f 4314opts_init(vnc_register_config);