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