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