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