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