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