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