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