Add SASL authentication support ("Daniel P. Berrange")
[qemu-kvm/fedora.git] / vnc.c
blob0b62000b9c9d2e80c78e4d2efc6d2fdefdf7bc7e
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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.
27 #include "vnc.h"
28 #include "sysemu.h"
29 #include "qemu_socket.h"
30 #include "qemu-timer.h"
32 #define VNC_REFRESH_INTERVAL (1000 / 30)
34 #include "vnc_keysym.h"
35 #include "d3des.h"
37 #define count_bits(c, v) { \
38 for (c = 0; v; v >>= 1) \
39 { \
40 c += v & 1; \
41 } \
45 static VncDisplay *vnc_display; /* needed for info vnc */
46 static DisplayChangeListener *dcl;
48 static char *addr_to_string(const char *format,
49 struct sockaddr_storage *sa,
50 socklen_t salen) {
51 char *addr;
52 char host[NI_MAXHOST];
53 char serv[NI_MAXSERV];
54 int err;
56 if ((err = getnameinfo((struct sockaddr *)sa, salen,
57 host, sizeof(host),
58 serv, sizeof(serv),
59 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
60 VNC_DEBUG("Cannot resolve address %d: %s\n",
61 err, gai_strerror(err));
62 return NULL;
65 if (asprintf(&addr, format, host, serv) < 0)
66 return NULL;
68 return addr;
72 char *vnc_socket_local_addr(const char *format, int fd) {
73 struct sockaddr_storage sa;
74 socklen_t salen;
76 salen = sizeof(sa);
77 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
78 return NULL;
80 return addr_to_string(format, &sa, salen);
84 char *vnc_socket_remote_addr(const char *format, int fd) {
85 struct sockaddr_storage sa;
86 socklen_t salen;
88 salen = sizeof(sa);
89 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
90 return NULL;
92 return addr_to_string(format, &sa, salen);
95 static const char *vnc_auth_name(VncDisplay *vd) {
96 switch (vd->auth) {
97 case VNC_AUTH_INVALID:
98 return "invalid";
99 case VNC_AUTH_NONE:
100 return "none";
101 case VNC_AUTH_VNC:
102 return "vnc";
103 case VNC_AUTH_RA2:
104 return "ra2";
105 case VNC_AUTH_RA2NE:
106 return "ra2ne";
107 case VNC_AUTH_TIGHT:
108 return "tight";
109 case VNC_AUTH_ULTRA:
110 return "ultra";
111 case VNC_AUTH_TLS:
112 return "tls";
113 case VNC_AUTH_VENCRYPT:
114 #ifdef CONFIG_VNC_TLS
115 switch (vd->subauth) {
116 case VNC_AUTH_VENCRYPT_PLAIN:
117 return "vencrypt+plain";
118 case VNC_AUTH_VENCRYPT_TLSNONE:
119 return "vencrypt+tls+none";
120 case VNC_AUTH_VENCRYPT_TLSVNC:
121 return "vencrypt+tls+vnc";
122 case VNC_AUTH_VENCRYPT_TLSPLAIN:
123 return "vencrypt+tls+plain";
124 case VNC_AUTH_VENCRYPT_X509NONE:
125 return "vencrypt+x509+none";
126 case VNC_AUTH_VENCRYPT_X509VNC:
127 return "vencrypt+x509+vnc";
128 case VNC_AUTH_VENCRYPT_X509PLAIN:
129 return "vencrypt+x509+plain";
130 case VNC_AUTH_VENCRYPT_TLSSASL:
131 return "vencrypt+tls+sasl";
132 case VNC_AUTH_VENCRYPT_X509SASL:
133 return "vencrypt+x509+sasl";
134 default:
135 return "vencrypt";
137 #else
138 return "vencrypt";
139 #endif
140 case VNC_AUTH_SASL:
141 return "sasl";
143 return "unknown";
146 #define VNC_SOCKET_FORMAT_PRETTY "local %s:%s"
148 static void do_info_vnc_client(VncState *client)
150 char *clientAddr =
151 vnc_socket_remote_addr(" address: %s:%s\n",
152 client->csock);
153 if (!clientAddr)
154 return;
156 term_puts("Client:\n");
157 term_puts(clientAddr);
158 free(clientAddr);
161 void do_info_vnc(void)
163 if (vnc_display == NULL || vnc_display->display == NULL) {
164 term_printf("Server: disabled\n");
165 } else {
166 char *serverAddr = vnc_socket_local_addr(" address: %s:%s\n",
167 vnc_display->lsock);
169 if (!serverAddr)
170 return;
172 term_puts("Server:\n");
173 term_puts(serverAddr);
174 free(serverAddr);
175 term_printf(" auth: %s\n", vnc_auth_name(vnc_display));
177 if (vnc_display->clients) {
178 VncState *client = vnc_display->clients;
179 while (client) {
180 do_info_vnc_client(client);
181 client = client->next;
183 } else {
184 term_printf("Client: none\n");
189 static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
190 return (vs->features & (1 << feature));
193 /* TODO
194 1) Get the queue working for IO.
195 2) there is some weirdness when using the -S option (the screen is grey
196 and not totally invalidated
197 3) resolutions > 1024
200 static void vnc_update_client(void *opaque);
201 static void vnc_disconnect_start(VncState *vs);
202 static void vnc_disconnect_finish(VncState *vs);
204 static void vnc_colordepth(VncState *vs);
206 static inline void vnc_set_bit(uint32_t *d, int k)
208 d[k >> 5] |= 1 << (k & 0x1f);
211 static inline void vnc_clear_bit(uint32_t *d, int k)
213 d[k >> 5] &= ~(1 << (k & 0x1f));
216 static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
218 int j;
220 j = 0;
221 while (n >= 32) {
222 d[j++] = -1;
223 n -= 32;
225 if (n > 0)
226 d[j++] = (1 << n) - 1;
227 while (j < nb_words)
228 d[j++] = 0;
231 static inline int vnc_get_bit(const uint32_t *d, int k)
233 return (d[k >> 5] >> (k & 0x1f)) & 1;
236 static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
237 int nb_words)
239 int i;
240 for(i = 0; i < nb_words; i++) {
241 if ((d1[i] & d2[i]) != 0)
242 return 1;
244 return 0;
247 static void vnc_update(VncState *vs, int x, int y, int w, int h)
249 int i;
251 h += y;
253 /* round x down to ensure the loop only spans one 16-pixel block per,
254 iteration. otherwise, if (x % 16) != 0, the last iteration may span
255 two 16-pixel blocks but we only mark the first as dirty
257 w += (x % 16);
258 x -= (x % 16);
260 x = MIN(x, vs->serverds.width);
261 y = MIN(y, vs->serverds.height);
262 w = MIN(x + w, vs->serverds.width) - x;
263 h = MIN(h, vs->serverds.height);
265 for (; y < h; y++)
266 for (i = 0; i < w; i += 16)
267 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
270 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
272 VncDisplay *vd = ds->opaque;
273 VncState *vs = vd->clients;
274 while (vs != NULL) {
275 vnc_update(vs, x, y, w, h);
276 vs = vs->next;
280 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
281 int32_t encoding)
283 vnc_write_u16(vs, x);
284 vnc_write_u16(vs, y);
285 vnc_write_u16(vs, w);
286 vnc_write_u16(vs, h);
288 vnc_write_s32(vs, encoding);
291 void buffer_reserve(Buffer *buffer, size_t len)
293 if ((buffer->capacity - buffer->offset) < len) {
294 buffer->capacity += (len + 1024);
295 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
296 if (buffer->buffer == NULL) {
297 fprintf(stderr, "vnc: out of memory\n");
298 exit(1);
303 int buffer_empty(Buffer *buffer)
305 return buffer->offset == 0;
308 uint8_t *buffer_end(Buffer *buffer)
310 return buffer->buffer + buffer->offset;
313 void buffer_reset(Buffer *buffer)
315 buffer->offset = 0;
318 void buffer_append(Buffer *buffer, const void *data, size_t len)
320 memcpy(buffer->buffer + buffer->offset, data, len);
321 buffer->offset += len;
324 static void vnc_resize(VncState *vs)
326 DisplayState *ds = vs->ds;
328 int size_changed;
330 vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
332 if (vs->old_data == NULL) {
333 fprintf(stderr, "vnc: memory allocation failed\n");
334 exit(1);
337 if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
338 console_color_init(ds);
339 vnc_colordepth(vs);
340 size_changed = ds_get_width(ds) != vs->serverds.width ||
341 ds_get_height(ds) != vs->serverds.height;
342 vs->serverds = *(ds->surface);
343 if (size_changed) {
344 if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
345 vnc_write_u8(vs, 0); /* msg id */
346 vnc_write_u8(vs, 0);
347 vnc_write_u16(vs, 1); /* number of rects */
348 vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
349 VNC_ENCODING_DESKTOPRESIZE);
350 vnc_flush(vs);
354 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
355 memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
358 static void vnc_dpy_resize(DisplayState *ds)
360 VncDisplay *vd = ds->opaque;
361 VncState *vs = vd->clients;
362 while (vs != NULL) {
363 vnc_resize(vs);
364 vs = vs->next;
368 /* fastest code */
369 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
371 vnc_write(vs, pixels, size);
374 /* slowest but generic code. */
375 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
377 uint8_t r, g, b;
379 r = ((((v & vs->serverds.pf.rmask) >> vs->serverds.pf.rshift) << vs->clientds.pf.rbits) >>
380 vs->serverds.pf.rbits);
381 g = ((((v & vs->serverds.pf.gmask) >> vs->serverds.pf.gshift) << vs->clientds.pf.gbits) >>
382 vs->serverds.pf.gbits);
383 b = ((((v & vs->serverds.pf.bmask) >> vs->serverds.pf.bshift) << vs->clientds.pf.bbits) >>
384 vs->serverds.pf.bbits);
385 v = (r << vs->clientds.pf.rshift) |
386 (g << vs->clientds.pf.gshift) |
387 (b << vs->clientds.pf.bshift);
388 switch(vs->clientds.pf.bytes_per_pixel) {
389 case 1:
390 buf[0] = v;
391 break;
392 case 2:
393 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
394 buf[0] = v >> 8;
395 buf[1] = v;
396 } else {
397 buf[1] = v >> 8;
398 buf[0] = v;
400 break;
401 default:
402 case 4:
403 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
404 buf[0] = v >> 24;
405 buf[1] = v >> 16;
406 buf[2] = v >> 8;
407 buf[3] = v;
408 } else {
409 buf[3] = v >> 24;
410 buf[2] = v >> 16;
411 buf[1] = v >> 8;
412 buf[0] = v;
414 break;
418 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
420 uint8_t buf[4];
422 if (vs->serverds.pf.bytes_per_pixel == 4) {
423 uint32_t *pixels = pixels1;
424 int n, i;
425 n = size >> 2;
426 for(i = 0; i < n; i++) {
427 vnc_convert_pixel(vs, buf, pixels[i]);
428 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
430 } else if (vs->serverds.pf.bytes_per_pixel == 2) {
431 uint16_t *pixels = pixels1;
432 int n, i;
433 n = size >> 1;
434 for(i = 0; i < n; i++) {
435 vnc_convert_pixel(vs, buf, pixels[i]);
436 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
438 } else if (vs->serverds.pf.bytes_per_pixel == 1) {
439 uint8_t *pixels = pixels1;
440 int n, i;
441 n = size;
442 for(i = 0; i < n; i++) {
443 vnc_convert_pixel(vs, buf, pixels[i]);
444 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
446 } else {
447 fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
451 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
453 int i;
454 uint8_t *row;
456 row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
457 for (i = 0; i < h; i++) {
458 vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
459 row += ds_get_linesize(vs->ds);
463 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
465 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
466 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
469 #define BPP 8
470 #include "vnchextile.h"
471 #undef BPP
473 #define BPP 16
474 #include "vnchextile.h"
475 #undef BPP
477 #define BPP 32
478 #include "vnchextile.h"
479 #undef BPP
481 #define GENERIC
482 #define BPP 8
483 #include "vnchextile.h"
484 #undef BPP
485 #undef GENERIC
487 #define GENERIC
488 #define BPP 16
489 #include "vnchextile.h"
490 #undef BPP
491 #undef GENERIC
493 #define GENERIC
494 #define BPP 32
495 #include "vnchextile.h"
496 #undef BPP
497 #undef GENERIC
499 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
501 int i, j;
502 int has_fg, has_bg;
503 uint8_t *last_fg, *last_bg;
505 last_fg = (uint8_t *) qemu_malloc(vs->serverds.pf.bytes_per_pixel);
506 last_bg = (uint8_t *) qemu_malloc(vs->serverds.pf.bytes_per_pixel);
507 has_fg = has_bg = 0;
508 for (j = y; j < (y + h); j += 16) {
509 for (i = x; i < (x + w); i += 16) {
510 vs->send_hextile_tile(vs, i, j,
511 MIN(16, x + w - i), MIN(16, y + h - j),
512 last_bg, last_fg, &has_bg, &has_fg);
515 free(last_fg);
516 free(last_bg);
520 static void vnc_zlib_init(VncState *vs)
522 int i;
523 for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++)
524 vs->zlib_stream[i].opaque = NULL;
527 static void vnc_zlib_start(VncState *vs)
529 buffer_reset(&vs->zlib);
531 // make the output buffer be the zlib buffer, so we can compress it later
532 vs->zlib_tmp = vs->output;
533 vs->output = vs->zlib;
536 static int vnc_zlib_stop(VncState *vs, int stream_id)
538 z_streamp zstream = &vs->zlib_stream[stream_id];
539 int previous_out;
541 // switch back to normal output/zlib buffers
542 vs->zlib = vs->output;
543 vs->output = vs->zlib_tmp;
545 // compress the zlib buffer
547 // initialize the stream
548 // XXX need one stream per session
549 if (zstream->opaque != vs) {
550 int err;
552 VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id);
553 VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
554 zstream->zalloc = Z_NULL;
555 zstream->zfree = Z_NULL;
557 err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
558 MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
560 if (err != Z_OK) {
561 fprintf(stderr, "VNC: error initializing zlib\n");
562 return -1;
565 zstream->opaque = vs;
568 // XXX what to do if tight_compression changed in between?
570 // reserve memory in output buffer
571 buffer_reserve(&vs->output, vs->zlib.offset + 64);
573 // set pointers
574 zstream->next_in = vs->zlib.buffer;
575 zstream->avail_in = vs->zlib.offset;
576 zstream->next_out = vs->output.buffer + vs->output.offset;
577 zstream->avail_out = vs->output.capacity - vs->output.offset;
578 zstream->data_type = Z_BINARY;
579 previous_out = zstream->total_out;
581 // start encoding
582 if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
583 fprintf(stderr, "VNC: error during zlib compression\n");
584 return -1;
587 vs->output.offset = vs->output.capacity - zstream->avail_out;
588 return zstream->total_out - previous_out;
591 static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)
593 int old_offset, new_offset, bytes_written;
595 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
597 // remember where we put in the follow-up size
598 old_offset = vs->output.offset;
599 vnc_write_s32(vs, 0);
601 // compress the stream
602 vnc_zlib_start(vs);
603 send_framebuffer_update_raw(vs, x, y, w, h);
604 bytes_written = vnc_zlib_stop(vs, 0);
606 if (bytes_written == -1)
607 return;
609 // hack in the size
610 new_offset = vs->output.offset;
611 vs->output.offset = old_offset;
612 vnc_write_u32(vs, bytes_written);
613 vs->output.offset = new_offset;
616 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
618 switch(vs->vnc_encoding) {
619 case VNC_ENCODING_ZLIB:
620 send_framebuffer_update_zlib(vs, x, y, w, h);
621 break;
622 case VNC_ENCODING_HEXTILE:
623 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
624 send_framebuffer_update_hextile(vs, x, y, w, h);
625 break;
626 default:
627 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
628 send_framebuffer_update_raw(vs, x, y, w, h);
629 break;
633 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
636 uint8_t *src_row;
637 uint8_t *dst_row;
638 int y,pitch,depth;
640 vnc_update_client(vs);
642 /* send bitblit op to the vnc client */
643 vnc_write_u8(vs, 0); /* msg id */
644 vnc_write_u8(vs, 0);
645 vnc_write_u16(vs, 1); /* number of rects */
646 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
647 vnc_write_u16(vs, src_x);
648 vnc_write_u16(vs, src_y);
649 vnc_flush(vs);
651 /* do bitblit op on the local surface too */
652 pitch = ds_get_linesize(vs->ds);
653 depth = ds_get_bytes_per_pixel(vs->ds);
654 src_row = ds_get_data(vs->ds) + pitch * src_y + depth * src_x;
655 dst_row = ds_get_data(vs->ds) + pitch * dst_y + depth * dst_x;
656 if (dst_y > src_y) {
657 /* copy backwards */
658 src_row += pitch * (h-1);
659 dst_row += pitch * (h-1);
660 pitch = -pitch;
662 for (y = 0; y < h; y++) {
663 memmove(dst_row, src_row, w * depth);
664 src_row += pitch;
665 dst_row += pitch;
669 static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
671 VncDisplay *vd = ds->opaque;
672 VncState *vs, *vn;
674 for (vs = vd->clients; vs != NULL; vs = vn) {
675 vn = vs->next;
676 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
677 vnc_update_client(vs);
678 /* vs might be free()ed here */
682 for (vs = vd->clients; vs != NULL; vs = vs->next) {
683 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
684 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
685 else /* TODO */
686 vnc_update(vs, dst_x, dst_y, w, h);
690 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
692 int h;
694 for (h = 1; h < (vs->serverds.height - y); h++) {
695 int tmp_x;
696 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
697 break;
698 for (tmp_x = last_x; tmp_x < x; tmp_x++)
699 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
702 return h;
705 static void vnc_update_client(void *opaque)
707 VncState *vs = opaque;
708 if (vs->need_update && vs->csock != -1) {
709 int y;
710 uint8_t *row;
711 char *old_row;
712 uint32_t width_mask[VNC_DIRTY_WORDS];
713 int n_rectangles;
714 int saved_offset;
715 int has_dirty = 0;
717 vga_hw_update();
719 vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
721 /* Walk through the dirty map and eliminate tiles that
722 really aren't dirty */
723 row = ds_get_data(vs->ds);
724 old_row = vs->old_data;
726 for (y = 0; y < ds_get_height(vs->ds); y++) {
727 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
728 int x;
729 uint8_t *ptr;
730 char *old_ptr;
732 ptr = row;
733 old_ptr = (char*)old_row;
735 for (x = 0; x < ds_get_width(vs->ds); x += 16) {
736 if (memcmp(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds)) == 0) {
737 vnc_clear_bit(vs->dirty_row[y], (x / 16));
738 } else {
739 has_dirty = 1;
740 memcpy(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds));
743 ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
744 old_ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
748 row += ds_get_linesize(vs->ds);
749 old_row += ds_get_linesize(vs->ds);
752 if (!has_dirty && !vs->audio_cap) {
753 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
754 return;
757 /* Count rectangles */
758 n_rectangles = 0;
759 vnc_write_u8(vs, 0); /* msg id */
760 vnc_write_u8(vs, 0);
761 saved_offset = vs->output.offset;
762 vnc_write_u16(vs, 0);
764 for (y = 0; y < vs->serverds.height; y++) {
765 int x;
766 int last_x = -1;
767 for (x = 0; x < vs->serverds.width / 16; x++) {
768 if (vnc_get_bit(vs->dirty_row[y], x)) {
769 if (last_x == -1) {
770 last_x = x;
772 vnc_clear_bit(vs->dirty_row[y], x);
773 } else {
774 if (last_x != -1) {
775 int h = find_dirty_height(vs, y, last_x, x);
776 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
777 n_rectangles++;
779 last_x = -1;
782 if (last_x != -1) {
783 int h = find_dirty_height(vs, y, last_x, x);
784 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
785 n_rectangles++;
788 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
789 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
790 vnc_flush(vs);
794 if (vs->csock != -1) {
795 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
796 } else {
797 vnc_disconnect_finish(vs);
802 /* audio */
803 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
805 VncState *vs = opaque;
807 switch (cmd) {
808 case AUD_CNOTIFY_DISABLE:
809 vnc_write_u8(vs, 255);
810 vnc_write_u8(vs, 1);
811 vnc_write_u16(vs, 0);
812 vnc_flush(vs);
813 break;
815 case AUD_CNOTIFY_ENABLE:
816 vnc_write_u8(vs, 255);
817 vnc_write_u8(vs, 1);
818 vnc_write_u16(vs, 1);
819 vnc_flush(vs);
820 break;
824 static void audio_capture_destroy(void *opaque)
828 static void audio_capture(void *opaque, void *buf, int size)
830 VncState *vs = opaque;
832 vnc_write_u8(vs, 255);
833 vnc_write_u8(vs, 1);
834 vnc_write_u16(vs, 2);
835 vnc_write_u32(vs, size);
836 vnc_write(vs, buf, size);
837 vnc_flush(vs);
840 static void audio_add(VncState *vs)
842 struct audio_capture_ops ops;
844 if (vs->audio_cap) {
845 term_printf ("audio already running\n");
846 return;
849 ops.notify = audio_capture_notify;
850 ops.destroy = audio_capture_destroy;
851 ops.capture = audio_capture;
853 vs->audio_cap = AUD_add_capture(NULL, &vs->as, &ops, vs);
854 if (!vs->audio_cap) {
855 term_printf ("Failed to add audio capture\n");
859 static void audio_del(VncState *vs)
861 if (vs->audio_cap) {
862 AUD_del_capture(vs->audio_cap, vs);
863 vs->audio_cap = NULL;
867 static void vnc_disconnect_start(VncState *vs)
869 if (vs->csock == -1)
870 return;
871 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
872 closesocket(vs->csock);
873 vs->csock = -1;
876 static void vnc_disconnect_finish(VncState *vs)
878 qemu_del_timer(vs->timer);
879 qemu_free_timer(vs->timer);
880 if (vs->input.buffer) qemu_free(vs->input.buffer);
881 if (vs->output.buffer) qemu_free(vs->output.buffer);
882 #ifdef CONFIG_VNC_TLS
883 vnc_tls_client_cleanup(vs);
884 #endif /* CONFIG_VNC_TLS */
885 #ifdef CONFIG_VNC_SASL
886 vnc_sasl_client_cleanup(vs);
887 #endif /* CONFIG_VNC_SASL */
888 audio_del(vs);
890 VncState *p, *parent = NULL;
891 for (p = vs->vd->clients; p != NULL; p = p->next) {
892 if (p == vs) {
893 if (parent)
894 parent->next = p->next;
895 else
896 vs->vd->clients = p->next;
897 break;
899 parent = p;
901 if (!vs->vd->clients)
902 dcl->idle = 1;
904 qemu_free(vs->old_data);
905 qemu_free(vs);
908 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
910 if (ret == 0 || ret == -1) {
911 if (ret == -1) {
912 switch (last_errno) {
913 case EINTR:
914 case EAGAIN:
915 #ifdef _WIN32
916 case WSAEWOULDBLOCK:
917 #endif
918 return 0;
919 default:
920 break;
924 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
925 vnc_disconnect_start(vs);
927 return 0;
929 return ret;
933 void vnc_client_error(VncState *vs)
935 VNC_DEBUG("Closing down client sock: protocol error\n");
936 vnc_disconnect_start(vs);
941 * Called to write a chunk of data to the client socket. The data may
942 * be the raw data, or may have already been encoded by SASL.
943 * The data will be written either straight onto the socket, or
944 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
946 * NB, it is theoretically possible to have 2 layers of encryption,
947 * both SASL, and this TLS layer. It is highly unlikely in practice
948 * though, since SASL encryption will typically be a no-op if TLS
949 * is active
951 * Returns the number of bytes written, which may be less than
952 * the requested 'datalen' if the socket would block. Returns
953 * -1 on error, and disconnects the client socket.
955 long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
957 long ret;
958 #ifdef CONFIG_VNC_TLS
959 if (vs->tls.session) {
960 ret = gnutls_write(vs->tls.session, data, datalen);
961 if (ret < 0) {
962 if (ret == GNUTLS_E_AGAIN)
963 errno = EAGAIN;
964 else
965 errno = EIO;
966 ret = -1;
968 } else
969 #endif /* CONFIG_VNC_TLS */
970 ret = send(vs->csock, data, datalen, 0);
971 VNC_DEBUG("Wrote wire %p %d -> %ld\n", data, datalen, ret);
972 return vnc_client_io_error(vs, ret, socket_error());
977 * Called to write buffered data to the client socket, when not
978 * using any SASL SSF encryption layers. Will write as much data
979 * as possible without blocking. If all buffered data is written,
980 * will switch the FD poll() handler back to read monitoring.
982 * Returns the number of bytes written, which may be less than
983 * the buffered output data if the socket would block. Returns
984 * -1 on error, and disconnects the client socket.
986 static long vnc_client_write_plain(VncState *vs)
988 long ret;
990 #ifdef CONFIG_VNC_SASL
991 VNC_DEBUG("Write Plain: Pending output %p size %d offset %d. Wait SSF %d\n",
992 vs->output.buffer, vs->output.capacity, vs->output.offset,
993 vs->sasl.waitWriteSSF);
995 if (vs->sasl.conn &&
996 vs->sasl.runSSF &&
997 vs->sasl.waitWriteSSF) {
998 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
999 if (ret)
1000 vs->sasl.waitWriteSSF -= ret;
1001 } else
1002 #endif /* CONFIG_VNC_SASL */
1003 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1004 if (!ret)
1005 return 0;
1007 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
1008 vs->output.offset -= ret;
1010 if (vs->output.offset == 0) {
1011 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1014 return ret;
1019 * First function called whenever there is data to be written to
1020 * the client socket. Will delegate actual work according to whether
1021 * SASL SSF layers are enabled (thus requiring encryption calls)
1023 void vnc_client_write(void *opaque)
1025 long ret;
1026 VncState *vs = opaque;
1028 #ifdef CONFIG_VNC_SASL
1029 if (vs->sasl.conn &&
1030 vs->sasl.runSSF &&
1031 !vs->sasl.waitWriteSSF)
1032 ret = vnc_client_write_sasl(vs);
1033 else
1034 #endif /* CONFIG_VNC_SASL */
1035 ret = vnc_client_write_plain(vs);
1038 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1040 vs->read_handler = func;
1041 vs->read_handler_expect = expecting;
1046 * Called to read a chunk of data from the client socket. The data may
1047 * be the raw data, or may need to be further decoded by SASL.
1048 * The data will be read either straight from to the socket, or
1049 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1051 * NB, it is theoretically possible to have 2 layers of encryption,
1052 * both SASL, and this TLS layer. It is highly unlikely in practice
1053 * though, since SASL encryption will typically be a no-op if TLS
1054 * is active
1056 * Returns the number of bytes read, which may be less than
1057 * the requested 'datalen' if the socket would block. Returns
1058 * -1 on error, and disconnects the client socket.
1060 long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1062 long ret;
1063 #ifdef CONFIG_VNC_TLS
1064 if (vs->tls.session) {
1065 ret = gnutls_read(vs->tls.session, data, datalen);
1066 if (ret < 0) {
1067 if (ret == GNUTLS_E_AGAIN)
1068 errno = EAGAIN;
1069 else
1070 errno = EIO;
1071 ret = -1;
1073 } else
1074 #endif /* CONFIG_VNC_TLS */
1075 ret = recv(vs->csock, data, datalen, 0);
1076 VNC_DEBUG("Read wire %p %d -> %ld\n", data, datalen, ret);
1077 return vnc_client_io_error(vs, ret, socket_error());
1082 * Called to read data from the client socket to the input buffer,
1083 * when not using any SASL SSF encryption layers. Will read as much
1084 * data as possible without blocking.
1086 * Returns the number of bytes read. Returns -1 on error, and
1087 * disconnects the client socket.
1089 static long vnc_client_read_plain(VncState *vs)
1091 int ret;
1092 VNC_DEBUG("Read plain %p size %d offset %d\n",
1093 vs->input.buffer, vs->input.capacity, vs->input.offset);
1094 buffer_reserve(&vs->input, 4096);
1095 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1096 if (!ret)
1097 return 0;
1098 vs->input.offset += ret;
1099 return ret;
1104 * First function called whenever there is more data to be read from
1105 * the client socket. Will delegate actual work according to whether
1106 * SASL SSF layers are enabled (thus requiring decryption calls)
1108 void vnc_client_read(void *opaque)
1110 VncState *vs = opaque;
1111 long ret;
1113 #ifdef CONFIG_VNC_SASL
1114 if (vs->sasl.conn && vs->sasl.runSSF)
1115 ret = vnc_client_read_sasl(vs);
1116 else
1117 #endif /* CONFIG_VNC_SASL */
1118 ret = vnc_client_read_plain(vs);
1119 if (!ret) {
1120 if (vs->csock == -1)
1121 vnc_disconnect_finish(vs);
1122 return;
1125 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1126 size_t len = vs->read_handler_expect;
1127 int ret;
1129 ret = vs->read_handler(vs, vs->input.buffer, len);
1130 if (vs->csock == -1) {
1131 vnc_disconnect_finish(vs);
1132 return;
1135 if (!ret) {
1136 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
1137 vs->input.offset -= len;
1138 } else {
1139 vs->read_handler_expect = ret;
1144 void vnc_write(VncState *vs, const void *data, size_t len)
1146 buffer_reserve(&vs->output, len);
1148 if (vs->csock != -1 && buffer_empty(&vs->output)) {
1149 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1152 buffer_append(&vs->output, data, len);
1155 void vnc_write_s32(VncState *vs, int32_t value)
1157 vnc_write_u32(vs, *(uint32_t *)&value);
1160 void vnc_write_u32(VncState *vs, uint32_t value)
1162 uint8_t buf[4];
1164 buf[0] = (value >> 24) & 0xFF;
1165 buf[1] = (value >> 16) & 0xFF;
1166 buf[2] = (value >> 8) & 0xFF;
1167 buf[3] = value & 0xFF;
1169 vnc_write(vs, buf, 4);
1172 void vnc_write_u16(VncState *vs, uint16_t value)
1174 uint8_t buf[2];
1176 buf[0] = (value >> 8) & 0xFF;
1177 buf[1] = value & 0xFF;
1179 vnc_write(vs, buf, 2);
1182 void vnc_write_u8(VncState *vs, uint8_t value)
1184 vnc_write(vs, (char *)&value, 1);
1187 void vnc_flush(VncState *vs)
1189 if (vs->csock != -1 && vs->output.offset)
1190 vnc_client_write(vs);
1193 uint8_t read_u8(uint8_t *data, size_t offset)
1195 return data[offset];
1198 uint16_t read_u16(uint8_t *data, size_t offset)
1200 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1203 int32_t read_s32(uint8_t *data, size_t offset)
1205 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1206 (data[offset + 2] << 8) | data[offset + 3]);
1209 uint32_t read_u32(uint8_t *data, size_t offset)
1211 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1212 (data[offset + 2] << 8) | data[offset + 3]);
1215 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1219 static void check_pointer_type_change(VncState *vs, int absolute)
1221 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1222 vnc_write_u8(vs, 0);
1223 vnc_write_u8(vs, 0);
1224 vnc_write_u16(vs, 1);
1225 vnc_framebuffer_update(vs, absolute, 0,
1226 ds_get_width(vs->ds), ds_get_height(vs->ds),
1227 VNC_ENCODING_POINTER_TYPE_CHANGE);
1228 vnc_flush(vs);
1230 vs->absolute = absolute;
1233 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1235 int buttons = 0;
1236 int dz = 0;
1238 if (button_mask & 0x01)
1239 buttons |= MOUSE_EVENT_LBUTTON;
1240 if (button_mask & 0x02)
1241 buttons |= MOUSE_EVENT_MBUTTON;
1242 if (button_mask & 0x04)
1243 buttons |= MOUSE_EVENT_RBUTTON;
1244 if (button_mask & 0x08)
1245 dz = -1;
1246 if (button_mask & 0x10)
1247 dz = 1;
1249 if (vs->absolute) {
1250 kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
1251 y * 0x7FFF / (ds_get_height(vs->ds) - 1),
1252 dz, buttons);
1253 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1254 x -= 0x7FFF;
1255 y -= 0x7FFF;
1257 kbd_mouse_event(x, y, dz, buttons);
1258 } else {
1259 if (vs->last_x != -1)
1260 kbd_mouse_event(x - vs->last_x,
1261 y - vs->last_y,
1262 dz, buttons);
1263 vs->last_x = x;
1264 vs->last_y = y;
1267 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1270 static void reset_keys(VncState *vs)
1272 int i;
1273 for(i = 0; i < 256; i++) {
1274 if (vs->modifiers_state[i]) {
1275 if (i & 0x80)
1276 kbd_put_keycode(0xe0);
1277 kbd_put_keycode(i | 0x80);
1278 vs->modifiers_state[i] = 0;
1283 static void press_key(VncState *vs, int keysym)
1285 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
1286 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
1289 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1291 /* QEMU console switch */
1292 switch(keycode) {
1293 case 0x2a: /* Left Shift */
1294 case 0x36: /* Right Shift */
1295 case 0x1d: /* Left CTRL */
1296 case 0x9d: /* Right CTRL */
1297 case 0x38: /* Left ALT */
1298 case 0xb8: /* Right ALT */
1299 if (down)
1300 vs->modifiers_state[keycode] = 1;
1301 else
1302 vs->modifiers_state[keycode] = 0;
1303 break;
1304 case 0x02 ... 0x0a: /* '1' to '9' keys */
1305 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1306 /* Reset the modifiers sent to the current console */
1307 reset_keys(vs);
1308 console_select(keycode - 0x02);
1309 return;
1311 break;
1312 case 0x3a: /* CapsLock */
1313 case 0x45: /* NumLock */
1314 if (!down)
1315 vs->modifiers_state[keycode] ^= 1;
1316 break;
1319 if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1320 /* If the numlock state needs to change then simulate an additional
1321 keypress before sending this one. This will happen if the user
1322 toggles numlock away from the VNC window.
1324 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1325 if (!vs->modifiers_state[0x45]) {
1326 vs->modifiers_state[0x45] = 1;
1327 press_key(vs, 0xff7f);
1329 } else {
1330 if (vs->modifiers_state[0x45]) {
1331 vs->modifiers_state[0x45] = 0;
1332 press_key(vs, 0xff7f);
1337 if (is_graphic_console()) {
1338 if (keycode & 0x80)
1339 kbd_put_keycode(0xe0);
1340 if (down)
1341 kbd_put_keycode(keycode & 0x7f);
1342 else
1343 kbd_put_keycode(keycode | 0x80);
1344 } else {
1345 /* QEMU console emulation */
1346 if (down) {
1347 switch (keycode) {
1348 case 0x2a: /* Left Shift */
1349 case 0x36: /* Right Shift */
1350 case 0x1d: /* Left CTRL */
1351 case 0x9d: /* Right CTRL */
1352 case 0x38: /* Left ALT */
1353 case 0xb8: /* Right ALT */
1354 break;
1355 case 0xc8:
1356 case 0x48:
1357 kbd_put_keysym(QEMU_KEY_UP);
1358 break;
1359 case 0xd0:
1360 case 0x50:
1361 kbd_put_keysym(QEMU_KEY_DOWN);
1362 break;
1363 case 0xcb:
1364 case 0x4b:
1365 kbd_put_keysym(QEMU_KEY_LEFT);
1366 break;
1367 case 0xcd:
1368 case 0x4d:
1369 kbd_put_keysym(QEMU_KEY_RIGHT);
1370 break;
1371 case 0xd3:
1372 case 0x53:
1373 kbd_put_keysym(QEMU_KEY_DELETE);
1374 break;
1375 case 0xc7:
1376 case 0x47:
1377 kbd_put_keysym(QEMU_KEY_HOME);
1378 break;
1379 case 0xcf:
1380 case 0x4f:
1381 kbd_put_keysym(QEMU_KEY_END);
1382 break;
1383 case 0xc9:
1384 case 0x49:
1385 kbd_put_keysym(QEMU_KEY_PAGEUP);
1386 break;
1387 case 0xd1:
1388 case 0x51:
1389 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1390 break;
1391 default:
1392 kbd_put_keysym(sym);
1393 break;
1399 static void key_event(VncState *vs, int down, uint32_t sym)
1401 int keycode;
1403 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1404 sym = sym - 'A' + 'a';
1406 keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
1407 do_key_event(vs, down, keycode, sym);
1410 static void ext_key_event(VncState *vs, int down,
1411 uint32_t sym, uint16_t keycode)
1413 /* if the user specifies a keyboard layout, always use it */
1414 if (keyboard_layout)
1415 key_event(vs, down, sym);
1416 else
1417 do_key_event(vs, down, keycode, sym);
1420 static void framebuffer_update_request(VncState *vs, int incremental,
1421 int x_position, int y_position,
1422 int w, int h)
1424 if (x_position > ds_get_width(vs->ds))
1425 x_position = ds_get_width(vs->ds);
1426 if (y_position > ds_get_height(vs->ds))
1427 y_position = ds_get_height(vs->ds);
1428 if (x_position + w >= ds_get_width(vs->ds))
1429 w = ds_get_width(vs->ds) - x_position;
1430 if (y_position + h >= ds_get_height(vs->ds))
1431 h = ds_get_height(vs->ds) - y_position;
1433 int i;
1434 vs->need_update = 1;
1435 if (!incremental) {
1436 char *old_row = vs->old_data + y_position * ds_get_linesize(vs->ds);
1438 for (i = 0; i < h; i++) {
1439 vnc_set_bits(vs->dirty_row[y_position + i],
1440 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1441 memset(old_row, 42, ds_get_width(vs->ds) * ds_get_bytes_per_pixel(vs->ds));
1442 old_row += ds_get_linesize(vs->ds);
1447 static void send_ext_key_event_ack(VncState *vs)
1449 vnc_write_u8(vs, 0);
1450 vnc_write_u8(vs, 0);
1451 vnc_write_u16(vs, 1);
1452 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1453 VNC_ENCODING_EXT_KEY_EVENT);
1454 vnc_flush(vs);
1457 static void send_ext_audio_ack(VncState *vs)
1459 vnc_write_u8(vs, 0);
1460 vnc_write_u8(vs, 0);
1461 vnc_write_u16(vs, 1);
1462 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1463 VNC_ENCODING_AUDIO);
1464 vnc_flush(vs);
1467 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1469 int i;
1470 unsigned int enc = 0;
1472 vnc_zlib_init(vs);
1473 vs->features = 0;
1474 vs->vnc_encoding = 0;
1475 vs->tight_compression = 9;
1476 vs->tight_quality = 9;
1477 vs->absolute = -1;
1479 for (i = n_encodings - 1; i >= 0; i--) {
1480 enc = encodings[i];
1481 switch (enc) {
1482 case VNC_ENCODING_RAW:
1483 vs->vnc_encoding = enc;
1484 break;
1485 case VNC_ENCODING_COPYRECT:
1486 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1487 break;
1488 case VNC_ENCODING_HEXTILE:
1489 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1490 vs->vnc_encoding = enc;
1491 break;
1492 case VNC_ENCODING_ZLIB:
1493 vs->features |= VNC_FEATURE_ZLIB_MASK;
1494 vs->vnc_encoding = enc;
1495 break;
1496 case VNC_ENCODING_DESKTOPRESIZE:
1497 vs->features |= VNC_FEATURE_RESIZE_MASK;
1498 break;
1499 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1500 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1501 break;
1502 case VNC_ENCODING_EXT_KEY_EVENT:
1503 send_ext_key_event_ack(vs);
1504 break;
1505 case VNC_ENCODING_AUDIO:
1506 send_ext_audio_ack(vs);
1507 break;
1508 case VNC_ENCODING_WMVi:
1509 vs->features |= VNC_FEATURE_WMVI_MASK;
1510 break;
1511 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1512 vs->tight_compression = (enc & 0x0F);
1513 break;
1514 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1515 vs->tight_quality = (enc & 0x0F);
1516 break;
1517 default:
1518 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1519 break;
1523 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1526 static void set_pixel_conversion(VncState *vs)
1528 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1529 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1530 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1531 vs->write_pixels = vnc_write_pixels_copy;
1532 switch (vs->ds->surface->pf.bits_per_pixel) {
1533 case 8:
1534 vs->send_hextile_tile = send_hextile_tile_8;
1535 break;
1536 case 16:
1537 vs->send_hextile_tile = send_hextile_tile_16;
1538 break;
1539 case 32:
1540 vs->send_hextile_tile = send_hextile_tile_32;
1541 break;
1543 } else {
1544 vs->write_pixels = vnc_write_pixels_generic;
1545 switch (vs->ds->surface->pf.bits_per_pixel) {
1546 case 8:
1547 vs->send_hextile_tile = send_hextile_tile_generic_8;
1548 break;
1549 case 16:
1550 vs->send_hextile_tile = send_hextile_tile_generic_16;
1551 break;
1552 case 32:
1553 vs->send_hextile_tile = send_hextile_tile_generic_32;
1554 break;
1559 static void set_pixel_format(VncState *vs,
1560 int bits_per_pixel, int depth,
1561 int big_endian_flag, int true_color_flag,
1562 int red_max, int green_max, int blue_max,
1563 int red_shift, int green_shift, int blue_shift)
1565 if (!true_color_flag) {
1566 vnc_client_error(vs);
1567 return;
1570 vs->clientds = vs->serverds;
1571 vs->clientds.pf.rmax = red_max;
1572 count_bits(vs->clientds.pf.rbits, red_max);
1573 vs->clientds.pf.rshift = red_shift;
1574 vs->clientds.pf.rmask = red_max << red_shift;
1575 vs->clientds.pf.gmax = green_max;
1576 count_bits(vs->clientds.pf.gbits, green_max);
1577 vs->clientds.pf.gshift = green_shift;
1578 vs->clientds.pf.gmask = green_max << green_shift;
1579 vs->clientds.pf.bmax = blue_max;
1580 count_bits(vs->clientds.pf.bbits, blue_max);
1581 vs->clientds.pf.bshift = blue_shift;
1582 vs->clientds.pf.bmask = blue_max << blue_shift;
1583 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1584 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1585 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1586 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1588 set_pixel_conversion(vs);
1590 vga_hw_invalidate();
1591 vga_hw_update();
1594 static void pixel_format_message (VncState *vs) {
1595 char pad[3] = { 0, 0, 0 };
1597 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1598 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
1600 #ifdef WORDS_BIGENDIAN
1601 vnc_write_u8(vs, 1); /* big-endian-flag */
1602 #else
1603 vnc_write_u8(vs, 0); /* big-endian-flag */
1604 #endif
1605 vnc_write_u8(vs, 1); /* true-color-flag */
1606 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1607 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1608 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1609 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1610 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1611 vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
1612 if (vs->ds->surface->pf.bits_per_pixel == 32)
1613 vs->send_hextile_tile = send_hextile_tile_32;
1614 else if (vs->ds->surface->pf.bits_per_pixel == 16)
1615 vs->send_hextile_tile = send_hextile_tile_16;
1616 else if (vs->ds->surface->pf.bits_per_pixel == 8)
1617 vs->send_hextile_tile = send_hextile_tile_8;
1618 vs->clientds = *(vs->ds->surface);
1619 vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
1620 vs->write_pixels = vnc_write_pixels_copy;
1622 vnc_write(vs, pad, 3); /* padding */
1625 static void vnc_dpy_setdata(DisplayState *ds)
1627 /* We don't have to do anything */
1630 static void vnc_colordepth(VncState *vs)
1632 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
1633 /* Sending a WMVi message to notify the client*/
1634 vnc_write_u8(vs, 0); /* msg id */
1635 vnc_write_u8(vs, 0);
1636 vnc_write_u16(vs, 1); /* number of rects */
1637 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
1638 ds_get_height(vs->ds), VNC_ENCODING_WMVi);
1639 pixel_format_message(vs);
1640 vnc_flush(vs);
1641 } else {
1642 set_pixel_conversion(vs);
1646 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1648 int i;
1649 uint16_t limit;
1651 switch (data[0]) {
1652 case 0:
1653 if (len == 1)
1654 return 20;
1656 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1657 read_u8(data, 6), read_u8(data, 7),
1658 read_u16(data, 8), read_u16(data, 10),
1659 read_u16(data, 12), read_u8(data, 14),
1660 read_u8(data, 15), read_u8(data, 16));
1661 break;
1662 case 2:
1663 if (len == 1)
1664 return 4;
1666 if (len == 4) {
1667 limit = read_u16(data, 2);
1668 if (limit > 0)
1669 return 4 + (limit * 4);
1670 } else
1671 limit = read_u16(data, 2);
1673 for (i = 0; i < limit; i++) {
1674 int32_t val = read_s32(data, 4 + (i * 4));
1675 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1678 set_encodings(vs, (int32_t *)(data + 4), limit);
1679 break;
1680 case 3:
1681 if (len == 1)
1682 return 10;
1684 framebuffer_update_request(vs,
1685 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1686 read_u16(data, 6), read_u16(data, 8));
1687 break;
1688 case 4:
1689 if (len == 1)
1690 return 8;
1692 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1693 break;
1694 case 5:
1695 if (len == 1)
1696 return 6;
1698 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1699 break;
1700 case 6:
1701 if (len == 1)
1702 return 8;
1704 if (len == 8) {
1705 uint32_t dlen = read_u32(data, 4);
1706 if (dlen > 0)
1707 return 8 + dlen;
1710 client_cut_text(vs, read_u32(data, 4), data + 8);
1711 break;
1712 case 255:
1713 if (len == 1)
1714 return 2;
1716 switch (read_u8(data, 1)) {
1717 case 0:
1718 if (len == 2)
1719 return 12;
1721 ext_key_event(vs, read_u16(data, 2),
1722 read_u32(data, 4), read_u32(data, 8));
1723 break;
1724 case 1:
1725 if (len == 2)
1726 return 4;
1728 switch (read_u16 (data, 2)) {
1729 case 0:
1730 audio_add(vs);
1731 break;
1732 case 1:
1733 audio_del(vs);
1734 break;
1735 case 2:
1736 if (len == 4)
1737 return 10;
1738 switch (read_u8(data, 4)) {
1739 case 0: vs->as.fmt = AUD_FMT_U8; break;
1740 case 1: vs->as.fmt = AUD_FMT_S8; break;
1741 case 2: vs->as.fmt = AUD_FMT_U16; break;
1742 case 3: vs->as.fmt = AUD_FMT_S16; break;
1743 case 4: vs->as.fmt = AUD_FMT_U32; break;
1744 case 5: vs->as.fmt = AUD_FMT_S32; break;
1745 default:
1746 printf("Invalid audio format %d\n", read_u8(data, 4));
1747 vnc_client_error(vs);
1748 break;
1750 vs->as.nchannels = read_u8(data, 5);
1751 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
1752 printf("Invalid audio channel coount %d\n",
1753 read_u8(data, 5));
1754 vnc_client_error(vs);
1755 break;
1757 vs->as.freq = read_u32(data, 6);
1758 break;
1759 default:
1760 printf ("Invalid audio message %d\n", read_u8(data, 4));
1761 vnc_client_error(vs);
1762 break;
1764 break;
1766 default:
1767 printf("Msg: %d\n", read_u16(data, 0));
1768 vnc_client_error(vs);
1769 break;
1771 break;
1772 default:
1773 printf("Msg: %d\n", data[0]);
1774 vnc_client_error(vs);
1775 break;
1778 vnc_read_when(vs, protocol_client_msg, 1);
1779 return 0;
1782 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1784 char buf[1024];
1785 int size;
1787 vnc_write_u16(vs, ds_get_width(vs->ds));
1788 vnc_write_u16(vs, ds_get_height(vs->ds));
1790 pixel_format_message(vs);
1792 if (qemu_name)
1793 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1794 else
1795 size = snprintf(buf, sizeof(buf), "QEMU");
1797 vnc_write_u32(vs, size);
1798 vnc_write(vs, buf, size);
1799 vnc_flush(vs);
1801 vnc_read_when(vs, protocol_client_msg, 1);
1803 return 0;
1806 void start_client_init(VncState *vs)
1808 vnc_read_when(vs, protocol_client_init, 1);
1811 static void make_challenge(VncState *vs)
1813 int i;
1815 srand(time(NULL)+getpid()+getpid()*987654+rand());
1817 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1818 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1821 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1823 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1824 int i, j, pwlen;
1825 unsigned char key[8];
1827 if (!vs->vd->password || !vs->vd->password[0]) {
1828 VNC_DEBUG("No password configured on server");
1829 vnc_write_u32(vs, 1); /* Reject auth */
1830 if (vs->minor >= 8) {
1831 static const char err[] = "Authentication failed";
1832 vnc_write_u32(vs, sizeof(err));
1833 vnc_write(vs, err, sizeof(err));
1835 vnc_flush(vs);
1836 vnc_client_error(vs);
1837 return 0;
1840 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1842 /* Calculate the expected challenge response */
1843 pwlen = strlen(vs->vd->password);
1844 for (i=0; i<sizeof(key); i++)
1845 key[i] = i<pwlen ? vs->vd->password[i] : 0;
1846 deskey(key, EN0);
1847 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1848 des(response+j, response+j);
1850 /* Compare expected vs actual challenge response */
1851 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1852 VNC_DEBUG("Client challenge reponse did not match\n");
1853 vnc_write_u32(vs, 1); /* Reject auth */
1854 if (vs->minor >= 8) {
1855 static const char err[] = "Authentication failed";
1856 vnc_write_u32(vs, sizeof(err));
1857 vnc_write(vs, err, sizeof(err));
1859 vnc_flush(vs);
1860 vnc_client_error(vs);
1861 } else {
1862 VNC_DEBUG("Accepting VNC challenge response\n");
1863 vnc_write_u32(vs, 0); /* Accept auth */
1864 vnc_flush(vs);
1866 start_client_init(vs);
1868 return 0;
1871 void start_auth_vnc(VncState *vs)
1873 make_challenge(vs);
1874 /* Send client a 'random' challenge */
1875 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1876 vnc_flush(vs);
1878 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1882 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1884 /* We only advertise 1 auth scheme at a time, so client
1885 * must pick the one we sent. Verify this */
1886 if (data[0] != vs->vd->auth) { /* Reject auth */
1887 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1888 vnc_write_u32(vs, 1);
1889 if (vs->minor >= 8) {
1890 static const char err[] = "Authentication failed";
1891 vnc_write_u32(vs, sizeof(err));
1892 vnc_write(vs, err, sizeof(err));
1894 vnc_client_error(vs);
1895 } else { /* Accept requested auth */
1896 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1897 switch (vs->vd->auth) {
1898 case VNC_AUTH_NONE:
1899 VNC_DEBUG("Accept auth none\n");
1900 if (vs->minor >= 8) {
1901 vnc_write_u32(vs, 0); /* Accept auth completion */
1902 vnc_flush(vs);
1904 start_client_init(vs);
1905 break;
1907 case VNC_AUTH_VNC:
1908 VNC_DEBUG("Start VNC auth\n");
1909 start_auth_vnc(vs);
1910 break;
1912 #ifdef CONFIG_VNC_TLS
1913 case VNC_AUTH_VENCRYPT:
1914 VNC_DEBUG("Accept VeNCrypt auth\n");;
1915 start_auth_vencrypt(vs);
1916 break;
1917 #endif /* CONFIG_VNC_TLS */
1919 #ifdef CONFIG_VNC_SASL
1920 case VNC_AUTH_SASL:
1921 VNC_DEBUG("Accept SASL auth\n");
1922 start_auth_sasl(vs);
1923 break;
1924 #endif /* CONFIG_VNC_SASL */
1926 default: /* Should not be possible, but just in case */
1927 VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
1928 vnc_write_u8(vs, 1);
1929 if (vs->minor >= 8) {
1930 static const char err[] = "Authentication failed";
1931 vnc_write_u32(vs, sizeof(err));
1932 vnc_write(vs, err, sizeof(err));
1934 vnc_client_error(vs);
1937 return 0;
1940 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1942 char local[13];
1944 memcpy(local, version, 12);
1945 local[12] = 0;
1947 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1948 VNC_DEBUG("Malformed protocol version %s\n", local);
1949 vnc_client_error(vs);
1950 return 0;
1952 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1953 if (vs->major != 3 ||
1954 (vs->minor != 3 &&
1955 vs->minor != 4 &&
1956 vs->minor != 5 &&
1957 vs->minor != 7 &&
1958 vs->minor != 8)) {
1959 VNC_DEBUG("Unsupported client version\n");
1960 vnc_write_u32(vs, VNC_AUTH_INVALID);
1961 vnc_flush(vs);
1962 vnc_client_error(vs);
1963 return 0;
1965 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1966 * as equivalent to v3.3 by servers
1968 if (vs->minor == 4 || vs->minor == 5)
1969 vs->minor = 3;
1971 if (vs->minor == 3) {
1972 if (vs->vd->auth == VNC_AUTH_NONE) {
1973 VNC_DEBUG("Tell client auth none\n");
1974 vnc_write_u32(vs, vs->vd->auth);
1975 vnc_flush(vs);
1976 start_client_init(vs);
1977 } else if (vs->vd->auth == VNC_AUTH_VNC) {
1978 VNC_DEBUG("Tell client VNC auth\n");
1979 vnc_write_u32(vs, vs->vd->auth);
1980 vnc_flush(vs);
1981 start_auth_vnc(vs);
1982 } else {
1983 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
1984 vnc_write_u32(vs, VNC_AUTH_INVALID);
1985 vnc_flush(vs);
1986 vnc_client_error(vs);
1988 } else {
1989 VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
1990 vnc_write_u8(vs, 1); /* num auth */
1991 vnc_write_u8(vs, vs->vd->auth);
1992 vnc_read_when(vs, protocol_client_auth, 1);
1993 vnc_flush(vs);
1996 return 0;
1999 static void vnc_connect(VncDisplay *vd, int csock)
2001 VncState *vs = qemu_mallocz(sizeof(VncState));
2002 vs->csock = csock;
2004 VNC_DEBUG("New client on socket %d\n", csock);
2005 dcl->idle = 0;
2006 socket_set_nonblock(vs->csock);
2007 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
2009 vs->vd = vd;
2010 vs->ds = vd->ds;
2011 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
2012 vs->last_x = -1;
2013 vs->last_y = -1;
2015 vs->as.freq = 44100;
2016 vs->as.nchannels = 2;
2017 vs->as.fmt = AUD_FMT_S16;
2018 vs->as.endianness = 0;
2020 vnc_resize(vs);
2021 vnc_write(vs, "RFB 003.008\n", 12);
2022 vnc_flush(vs);
2023 vnc_read_when(vs, protocol_version, 12);
2024 memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
2025 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
2026 reset_keys(vs);
2028 vs->next = vd->clients;
2029 vd->clients = vs;
2031 vnc_update_client(vs);
2032 /* vs might be free()ed here */
2035 static void vnc_listen_read(void *opaque)
2037 VncDisplay *vs = opaque;
2038 struct sockaddr_in addr;
2039 socklen_t addrlen = sizeof(addr);
2041 /* Catch-up */
2042 vga_hw_update();
2044 int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2045 if (csock != -1) {
2046 vnc_connect(vs, csock);
2050 void vnc_display_init(DisplayState *ds)
2052 VncDisplay *vs = qemu_mallocz(sizeof(*vs));
2054 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
2056 ds->opaque = vs;
2057 dcl->idle = 1;
2058 vnc_display = vs;
2060 vs->lsock = -1;
2062 vs->ds = ds;
2064 if (keyboard_layout)
2065 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
2066 else
2067 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
2069 if (!vs->kbd_layout)
2070 exit(1);
2072 dcl->dpy_copy = vnc_dpy_copy;
2073 dcl->dpy_update = vnc_dpy_update;
2074 dcl->dpy_resize = vnc_dpy_resize;
2075 dcl->dpy_setdata = vnc_dpy_setdata;
2076 register_displaychangelistener(ds, dcl);
2080 void vnc_display_close(DisplayState *ds)
2082 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2084 if (!vs)
2085 return;
2086 if (vs->display) {
2087 qemu_free(vs->display);
2088 vs->display = NULL;
2090 if (vs->lsock != -1) {
2091 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2092 close(vs->lsock);
2093 vs->lsock = -1;
2095 vs->auth = VNC_AUTH_INVALID;
2096 #ifdef CONFIG_VNC_TLS
2097 vs->subauth = VNC_AUTH_INVALID;
2098 vs->tls.x509verify = 0;
2099 #endif
2102 int vnc_display_password(DisplayState *ds, const char *password)
2104 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2106 if (vs->password) {
2107 qemu_free(vs->password);
2108 vs->password = NULL;
2110 if (password && password[0]) {
2111 if (!(vs->password = qemu_strdup(password)))
2112 return -1;
2115 return 0;
2118 int vnc_display_open(DisplayState *ds, const char *display)
2120 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2121 const char *options;
2122 int password = 0;
2123 int reverse = 0;
2124 int to_port = 0;
2125 #ifdef CONFIG_VNC_TLS
2126 int tls = 0, x509 = 0;
2127 #endif
2128 #ifdef CONFIG_VNC_SASL
2129 int sasl = 0;
2130 int saslErr;
2131 #endif
2133 if (!vnc_display)
2134 return -1;
2135 vnc_display_close(ds);
2136 if (strcmp(display, "none") == 0)
2137 return 0;
2139 if (!(vs->display = strdup(display)))
2140 return -1;
2142 options = display;
2143 while ((options = strchr(options, ','))) {
2144 options++;
2145 if (strncmp(options, "password", 8) == 0) {
2146 password = 1; /* Require password auth */
2147 } else if (strncmp(options, "reverse", 7) == 0) {
2148 reverse = 1;
2149 } else if (strncmp(options, "to=", 3) == 0) {
2150 to_port = atoi(options+3) + 5900;
2151 #ifdef CONFIG_VNC_SASL
2152 } else if (strncmp(options, "sasl", 4) == 0) {
2153 sasl = 1; /* Require SASL auth */
2154 #endif
2155 #ifdef CONFIG_VNC_TLS
2156 } else if (strncmp(options, "tls", 3) == 0) {
2157 tls = 1; /* Require TLS */
2158 } else if (strncmp(options, "x509", 4) == 0) {
2159 char *start, *end;
2160 x509 = 1; /* Require x509 certificates */
2161 if (strncmp(options, "x509verify", 10) == 0)
2162 vs->tls.x509verify = 1; /* ...and verify client certs */
2164 /* Now check for 'x509=/some/path' postfix
2165 * and use that to setup x509 certificate/key paths */
2166 start = strchr(options, '=');
2167 end = strchr(options, ',');
2168 if (start && (!end || (start < end))) {
2169 int len = end ? end-(start+1) : strlen(start+1);
2170 char *path = qemu_strndup(start + 1, len);
2172 VNC_DEBUG("Trying certificate path '%s'\n", path);
2173 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2174 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2175 qemu_free(path);
2176 qemu_free(vs->display);
2177 vs->display = NULL;
2178 return -1;
2180 qemu_free(path);
2181 } else {
2182 fprintf(stderr, "No certificate path provided\n");
2183 qemu_free(vs->display);
2184 vs->display = NULL;
2185 return -1;
2187 #endif
2192 * Combinations we support here:
2194 * - no-auth (clear text, no auth)
2195 * - password (clear text, weak auth)
2196 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
2197 * - tls (encrypt, weak anonymous creds, no auth)
2198 * - tls + password (encrypt, weak anonymous creds, weak auth)
2199 * - tls + sasl (encrypt, weak anonymous creds, good auth)
2200 * - tls + x509 (encrypt, good x509 creds, no auth)
2201 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
2202 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
2204 * NB1. TLS is a stackable auth scheme.
2205 * NB2. the x509 schemes have option to validate a client cert dname
2207 if (password) {
2208 #ifdef CONFIG_VNC_TLS
2209 if (tls) {
2210 vs->auth = VNC_AUTH_VENCRYPT;
2211 if (x509) {
2212 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2213 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2214 } else {
2215 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2216 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2218 } else {
2219 #endif /* CONFIG_VNC_TLS */
2220 VNC_DEBUG("Initializing VNC server with password auth\n");
2221 vs->auth = VNC_AUTH_VNC;
2222 #ifdef CONFIG_VNC_TLS
2223 vs->subauth = VNC_AUTH_INVALID;
2225 #endif /* CONFIG_VNC_TLS */
2226 #ifdef CONFIG_VNC_SASL
2227 } else if (sasl) {
2228 #ifdef CONFIG_VNC_TLS
2229 if (tls) {
2230 vs->auth = VNC_AUTH_VENCRYPT;
2231 if (x509) {
2232 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
2233 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
2234 } else {
2235 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
2236 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
2238 } else {
2239 #endif /* CONFIG_VNC_TLS */
2240 VNC_DEBUG("Initializing VNC server with SASL auth\n");
2241 vs->auth = VNC_AUTH_SASL;
2242 #ifdef CONFIG_VNC_TLS
2243 vs->subauth = VNC_AUTH_INVALID;
2245 #endif /* CONFIG_VNC_TLS */
2246 #endif /* CONFIG_VNC_SASL */
2247 } else {
2248 #ifdef CONFIG_VNC_TLS
2249 if (tls) {
2250 vs->auth = VNC_AUTH_VENCRYPT;
2251 if (x509) {
2252 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2253 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2254 } else {
2255 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2256 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2258 } else {
2259 #endif
2260 VNC_DEBUG("Initializing VNC server with no auth\n");
2261 vs->auth = VNC_AUTH_NONE;
2262 #ifdef CONFIG_VNC_TLS
2263 vs->subauth = VNC_AUTH_INVALID;
2265 #endif
2268 #ifdef CONFIG_VNC_SASL
2269 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2270 fprintf(stderr, "Failed to initialize SASL auth %s",
2271 sasl_errstring(saslErr, NULL, NULL));
2272 free(vs->display);
2273 vs->display = NULL;
2274 return -1;
2276 #endif
2278 if (reverse) {
2279 /* connect to viewer */
2280 if (strncmp(display, "unix:", 5) == 0)
2281 vs->lsock = unix_connect(display+5);
2282 else
2283 vs->lsock = inet_connect(display, SOCK_STREAM);
2284 if (-1 == vs->lsock) {
2285 free(vs->display);
2286 vs->display = NULL;
2287 return -1;
2288 } else {
2289 int csock = vs->lsock;
2290 vs->lsock = -1;
2291 vnc_connect(vs, csock);
2293 return 0;
2295 } else {
2296 /* listen for connects */
2297 char *dpy;
2298 dpy = qemu_malloc(256);
2299 if (strncmp(display, "unix:", 5) == 0) {
2300 pstrcpy(dpy, 256, "unix:");
2301 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
2302 } else {
2303 vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
2305 if (-1 == vs->lsock) {
2306 free(dpy);
2307 return -1;
2308 } else {
2309 free(vs->display);
2310 vs->display = dpy;
2313 return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);