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