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