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