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