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