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