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