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