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