Fix livelocks debugger
[qemu-kvm/fedora.git] / vnc.c
blobf6ec5cf3819588b46ce287e41ab4337fdedce1b6
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
26 #include "qemu-common.h"
27 #include "console.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 "keymaps.c"
36 #include "d3des.h"
38 #if CONFIG_VNC_TLS
39 #include <gnutls/gnutls.h>
40 #include <gnutls/x509.h>
41 #endif /* CONFIG_VNC_TLS */
43 // #define _VNC_DEBUG 1
45 #if _VNC_DEBUG
46 #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
48 #if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
49 /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
50 static void vnc_debug_gnutls_log(int level, const char* str) {
51 VNC_DEBUG("%d %s", level, str);
53 #endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
54 #else
55 #define VNC_DEBUG(fmt, ...) do { } while (0)
56 #endif
59 typedef struct Buffer
61 size_t capacity;
62 size_t offset;
63 uint8_t *buffer;
64 } Buffer;
66 typedef struct VncState VncState;
68 typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
70 typedef void VncWritePixels(VncState *vs, void *data, int size);
72 typedef void VncSendHextileTile(VncState *vs,
73 int x, int y, int w, int h,
74 uint32_t *last_bg,
75 uint32_t *last_fg,
76 int *has_bg, int *has_fg);
78 #define VNC_MAX_WIDTH 2048
79 #define VNC_MAX_HEIGHT 2048
80 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
82 #define VNC_AUTH_CHALLENGE_SIZE 16
84 enum {
85 VNC_AUTH_INVALID = 0,
86 VNC_AUTH_NONE = 1,
87 VNC_AUTH_VNC = 2,
88 VNC_AUTH_RA2 = 5,
89 VNC_AUTH_RA2NE = 6,
90 VNC_AUTH_TIGHT = 16,
91 VNC_AUTH_ULTRA = 17,
92 VNC_AUTH_TLS = 18,
93 VNC_AUTH_VENCRYPT = 19
96 #if CONFIG_VNC_TLS
97 enum {
98 VNC_WIREMODE_CLEAR,
99 VNC_WIREMODE_TLS,
102 enum {
103 VNC_AUTH_VENCRYPT_PLAIN = 256,
104 VNC_AUTH_VENCRYPT_TLSNONE = 257,
105 VNC_AUTH_VENCRYPT_TLSVNC = 258,
106 VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
107 VNC_AUTH_VENCRYPT_X509NONE = 260,
108 VNC_AUTH_VENCRYPT_X509VNC = 261,
109 VNC_AUTH_VENCRYPT_X509PLAIN = 262,
112 #if CONFIG_VNC_TLS
113 #define X509_CA_CERT_FILE "ca-cert.pem"
114 #define X509_CA_CRL_FILE "ca-crl.pem"
115 #define X509_SERVER_KEY_FILE "server-key.pem"
116 #define X509_SERVER_CERT_FILE "server-cert.pem"
117 #endif
119 #endif /* CONFIG_VNC_TLS */
121 struct VncState
123 QEMUTimer *timer;
124 int lsock;
125 int csock;
126 DisplayState *ds;
127 int need_update;
128 int width;
129 int height;
130 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
131 char *old_data;
132 int depth; /* internal VNC frame buffer byte per pixel */
133 int has_resize;
134 int has_hextile;
135 int has_pointer_type_change;
136 int absolute;
137 int last_x;
138 int last_y;
140 int major;
141 int minor;
143 char *display;
144 char *password;
145 int auth;
146 #if CONFIG_VNC_TLS
147 int subauth;
148 int x509verify;
150 char *x509cacert;
151 char *x509cacrl;
152 char *x509cert;
153 char *x509key;
154 #endif
155 char challenge[VNC_AUTH_CHALLENGE_SIZE];
157 #if CONFIG_VNC_TLS
158 int wiremode;
159 gnutls_session_t tls_session;
160 #endif
162 Buffer output;
163 Buffer input;
164 kbd_layout_t *kbd_layout;
165 /* current output mode information */
166 VncWritePixels *write_pixels;
167 VncSendHextileTile *send_hextile_tile;
168 int pix_bpp, pix_big_endian;
169 int red_shift, red_max, red_shift1;
170 int green_shift, green_max, green_shift1;
171 int blue_shift, blue_max, blue_shift1;
173 VncReadEvent *read_handler;
174 size_t read_handler_expect;
175 /* input */
176 uint8_t modifiers_state[256];
179 static VncState *vnc_state; /* needed for info vnc */
181 void do_info_vnc(void)
183 if (vnc_state == NULL)
184 term_printf("VNC server disabled\n");
185 else {
186 term_printf("VNC server active on: ");
187 term_print_filename(vnc_state->display);
188 term_printf("\n");
190 if (vnc_state->csock == -1)
191 term_printf("No client connected\n");
192 else
193 term_printf("Client connected\n");
197 /* TODO
198 1) Get the queue working for IO.
199 2) there is some weirdness when using the -S option (the screen is grey
200 and not totally invalidated
201 3) resolutions > 1024
204 static void vnc_write(VncState *vs, const void *data, size_t len);
205 static void vnc_write_u32(VncState *vs, uint32_t value);
206 static void vnc_write_s32(VncState *vs, int32_t value);
207 static void vnc_write_u16(VncState *vs, uint16_t value);
208 static void vnc_write_u8(VncState *vs, uint8_t value);
209 static void vnc_flush(VncState *vs);
210 static void vnc_update_client(void *opaque);
211 static void vnc_client_read(void *opaque);
213 static inline void vnc_set_bit(uint32_t *d, int k)
215 d[k >> 5] |= 1 << (k & 0x1f);
218 static inline void vnc_clear_bit(uint32_t *d, int k)
220 d[k >> 5] &= ~(1 << (k & 0x1f));
223 static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
225 int j;
227 j = 0;
228 while (n >= 32) {
229 d[j++] = -1;
230 n -= 32;
232 if (n > 0)
233 d[j++] = (1 << n) - 1;
234 while (j < nb_words)
235 d[j++] = 0;
238 static inline int vnc_get_bit(const uint32_t *d, int k)
240 return (d[k >> 5] >> (k & 0x1f)) & 1;
243 static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
244 int nb_words)
246 int i;
247 for(i = 0; i < nb_words; i++) {
248 if ((d1[i] & d2[i]) != 0)
249 return 1;
251 return 0;
254 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
256 VncState *vs = ds->opaque;
257 int i;
259 h += y;
261 /* round x down to ensure the loop only spans one 16-pixel block per,
262 iteration. otherwise, if (x % 16) != 0, the last iteration may span
263 two 16-pixel blocks but we only mark the first as dirty
265 w += (x % 16);
266 x -= (x % 16);
268 for (; y < h; y++)
269 for (i = 0; i < w; i += 16)
270 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
273 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
274 int32_t encoding)
276 vnc_write_u16(vs, x);
277 vnc_write_u16(vs, y);
278 vnc_write_u16(vs, w);
279 vnc_write_u16(vs, h);
281 vnc_write_s32(vs, encoding);
284 static void vnc_dpy_resize(DisplayState *ds, int w, int h)
286 int size_changed;
287 VncState *vs = ds->opaque;
289 ds->data = realloc(ds->data, w * h * vs->depth);
290 vs->old_data = realloc(vs->old_data, w * h * vs->depth);
292 if (ds->data == NULL || vs->old_data == NULL) {
293 fprintf(stderr, "vnc: memory allocation failed\n");
294 exit(1);
297 if (ds->depth != vs->depth * 8) {
298 ds->depth = vs->depth * 8;
299 console_color_init(ds);
301 size_changed = ds->width != w || ds->height != h;
302 ds->width = w;
303 ds->height = h;
304 ds->linesize = w * vs->depth;
305 if (vs->csock != -1 && vs->has_resize && size_changed) {
306 vnc_write_u8(vs, 0); /* msg id */
307 vnc_write_u8(vs, 0);
308 vnc_write_u16(vs, 1); /* number of rects */
309 vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
310 vnc_flush(vs);
311 vs->width = ds->width;
312 vs->height = ds->height;
316 /* fastest code */
317 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
319 vnc_write(vs, pixels, size);
322 /* slowest but generic code. */
323 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
325 unsigned int r, g, b;
327 r = (v >> vs->red_shift1) & vs->red_max;
328 g = (v >> vs->green_shift1) & vs->green_max;
329 b = (v >> vs->blue_shift1) & vs->blue_max;
330 v = (r << vs->red_shift) |
331 (g << vs->green_shift) |
332 (b << vs->blue_shift);
333 switch(vs->pix_bpp) {
334 case 1:
335 buf[0] = v;
336 break;
337 case 2:
338 if (vs->pix_big_endian) {
339 buf[0] = v >> 8;
340 buf[1] = v;
341 } else {
342 buf[1] = v >> 8;
343 buf[0] = v;
345 break;
346 default:
347 case 4:
348 if (vs->pix_big_endian) {
349 buf[0] = v >> 24;
350 buf[1] = v >> 16;
351 buf[2] = v >> 8;
352 buf[3] = v;
353 } else {
354 buf[3] = v >> 24;
355 buf[2] = v >> 16;
356 buf[1] = v >> 8;
357 buf[0] = v;
359 break;
363 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
365 uint32_t *pixels = pixels1;
366 uint8_t buf[4];
367 int n, i;
369 n = size >> 2;
370 for(i = 0; i < n; i++) {
371 vnc_convert_pixel(vs, buf, pixels[i]);
372 vnc_write(vs, buf, vs->pix_bpp);
376 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
378 int i;
379 uint8_t *row;
381 vnc_framebuffer_update(vs, x, y, w, h, 0);
383 row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
384 for (i = 0; i < h; i++) {
385 vs->write_pixels(vs, row, w * vs->depth);
386 row += vs->ds->linesize;
390 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
392 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
393 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
396 #define BPP 8
397 #include "vnchextile.h"
398 #undef BPP
400 #define BPP 16
401 #include "vnchextile.h"
402 #undef BPP
404 #define BPP 32
405 #include "vnchextile.h"
406 #undef BPP
408 #define GENERIC
409 #define BPP 32
410 #include "vnchextile.h"
411 #undef BPP
412 #undef GENERIC
414 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
416 int i, j;
417 int has_fg, has_bg;
418 uint32_t last_fg32, last_bg32;
420 vnc_framebuffer_update(vs, x, y, w, h, 5);
422 has_fg = has_bg = 0;
423 for (j = y; j < (y + h); j += 16) {
424 for (i = x; i < (x + w); i += 16) {
425 vs->send_hextile_tile(vs, i, j,
426 MIN(16, x + w - i), MIN(16, y + h - j),
427 &last_bg32, &last_fg32, &has_bg, &has_fg);
432 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
434 if (vs->has_hextile)
435 send_framebuffer_update_hextile(vs, x, y, w, h);
436 else
437 send_framebuffer_update_raw(vs, x, y, w, h);
440 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
442 int src, dst;
443 uint8_t *src_row;
444 uint8_t *dst_row;
445 char *old_row;
446 int y = 0;
447 int pitch = ds->linesize;
448 VncState *vs = ds->opaque;
450 vnc_update_client(vs);
452 if (dst_y > src_y) {
453 y = h - 1;
454 pitch = -pitch;
457 src = (ds->linesize * (src_y + y) + vs->depth * src_x);
458 dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
460 src_row = ds->data + src;
461 dst_row = ds->data + dst;
462 old_row = vs->old_data + dst;
464 for (y = 0; y < h; y++) {
465 memmove(old_row, src_row, w * vs->depth);
466 memmove(dst_row, src_row, w * vs->depth);
467 src_row += pitch;
468 dst_row += pitch;
469 old_row += pitch;
472 vnc_write_u8(vs, 0); /* msg id */
473 vnc_write_u8(vs, 0);
474 vnc_write_u16(vs, 1); /* number of rects */
475 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
476 vnc_write_u16(vs, src_x);
477 vnc_write_u16(vs, src_y);
478 vnc_flush(vs);
481 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
483 int h;
485 for (h = 1; h < (vs->height - y); h++) {
486 int tmp_x;
487 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
488 break;
489 for (tmp_x = last_x; tmp_x < x; tmp_x++)
490 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
493 return h;
496 static void vnc_update_client(void *opaque)
498 VncState *vs = opaque;
500 if (vs->need_update && vs->csock != -1) {
501 int y;
502 uint8_t *row;
503 char *old_row;
504 uint32_t width_mask[VNC_DIRTY_WORDS];
505 int n_rectangles;
506 int saved_offset;
507 int has_dirty = 0;
509 vga_hw_update();
511 vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
513 /* Walk through the dirty map and eliminate tiles that
514 really aren't dirty */
515 row = vs->ds->data;
516 old_row = vs->old_data;
518 for (y = 0; y < vs->height; y++) {
519 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
520 int x;
521 uint8_t *ptr;
522 char *old_ptr;
524 ptr = row;
525 old_ptr = (char*)old_row;
527 for (x = 0; x < vs->ds->width; x += 16) {
528 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
529 vnc_clear_bit(vs->dirty_row[y], (x / 16));
530 } else {
531 has_dirty = 1;
532 memcpy(old_ptr, ptr, 16 * vs->depth);
535 ptr += 16 * vs->depth;
536 old_ptr += 16 * vs->depth;
540 row += vs->ds->linesize;
541 old_row += vs->ds->linesize;
544 if (!has_dirty) {
545 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
546 return;
549 /* Count rectangles */
550 n_rectangles = 0;
551 vnc_write_u8(vs, 0); /* msg id */
552 vnc_write_u8(vs, 0);
553 saved_offset = vs->output.offset;
554 vnc_write_u16(vs, 0);
556 for (y = 0; y < vs->height; y++) {
557 int x;
558 int last_x = -1;
559 for (x = 0; x < vs->width / 16; x++) {
560 if (vnc_get_bit(vs->dirty_row[y], x)) {
561 if (last_x == -1) {
562 last_x = x;
564 vnc_clear_bit(vs->dirty_row[y], x);
565 } else {
566 if (last_x != -1) {
567 int h = find_dirty_height(vs, y, last_x, x);
568 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
569 n_rectangles++;
571 last_x = -1;
574 if (last_x != -1) {
575 int h = find_dirty_height(vs, y, last_x, x);
576 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
577 n_rectangles++;
580 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
581 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
582 vnc_flush(vs);
586 if (vs->csock != -1) {
587 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
592 static int vnc_listen_poll(void *opaque)
594 VncState *vs = opaque;
595 if (vs->csock == -1)
596 return 1;
597 return 0;
600 static void buffer_reserve(Buffer *buffer, size_t len)
602 if ((buffer->capacity - buffer->offset) < len) {
603 buffer->capacity += (len + 1024);
604 buffer->buffer = realloc(buffer->buffer, buffer->capacity);
605 if (buffer->buffer == NULL) {
606 fprintf(stderr, "vnc: out of memory\n");
607 exit(1);
612 static int buffer_empty(Buffer *buffer)
614 return buffer->offset == 0;
617 static uint8_t *buffer_end(Buffer *buffer)
619 return buffer->buffer + buffer->offset;
622 static void buffer_reset(Buffer *buffer)
624 buffer->offset = 0;
627 static void buffer_append(Buffer *buffer, const void *data, size_t len)
629 memcpy(buffer->buffer + buffer->offset, data, len);
630 buffer->offset += len;
633 static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
635 if (ret == 0 || ret == -1) {
636 if (ret == -1) {
637 switch (last_errno) {
638 case EINTR:
639 case EAGAIN:
640 #ifdef _WIN32
641 case WSAEWOULDBLOCK:
642 #endif
643 return 0;
644 default:
645 break;
649 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
650 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
651 closesocket(vs->csock);
652 vs->csock = -1;
653 buffer_reset(&vs->input);
654 buffer_reset(&vs->output);
655 vs->need_update = 0;
656 #if CONFIG_VNC_TLS
657 if (vs->tls_session) {
658 gnutls_deinit(vs->tls_session);
659 vs->tls_session = NULL;
661 vs->wiremode = VNC_WIREMODE_CLEAR;
662 #endif /* CONFIG_VNC_TLS */
663 return 0;
665 return ret;
668 static void vnc_client_error(VncState *vs)
670 vnc_client_io_error(vs, -1, EINVAL);
673 static void vnc_client_write(void *opaque)
675 long ret;
676 VncState *vs = opaque;
678 #if CONFIG_VNC_TLS
679 if (vs->tls_session) {
680 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
681 if (ret < 0) {
682 if (ret == GNUTLS_E_AGAIN)
683 errno = EAGAIN;
684 else
685 errno = EIO;
686 ret = -1;
688 } else
689 #endif /* CONFIG_VNC_TLS */
690 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
691 ret = vnc_client_io_error(vs, ret, socket_error());
692 if (!ret)
693 return;
695 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
696 vs->output.offset -= ret;
698 if (vs->output.offset == 0) {
699 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
703 static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
705 vs->read_handler = func;
706 vs->read_handler_expect = expecting;
709 static void vnc_client_read(void *opaque)
711 VncState *vs = opaque;
712 long ret;
714 buffer_reserve(&vs->input, 4096);
716 #if CONFIG_VNC_TLS
717 if (vs->tls_session) {
718 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
719 if (ret < 0) {
720 if (ret == GNUTLS_E_AGAIN)
721 errno = EAGAIN;
722 else
723 errno = EIO;
724 ret = -1;
726 } else
727 #endif /* CONFIG_VNC_TLS */
728 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
729 ret = vnc_client_io_error(vs, ret, socket_error());
730 if (!ret)
731 return;
733 vs->input.offset += ret;
735 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
736 size_t len = vs->read_handler_expect;
737 int ret;
739 ret = vs->read_handler(vs, vs->input.buffer, len);
740 if (vs->csock == -1)
741 return;
743 if (!ret) {
744 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
745 vs->input.offset -= len;
746 } else {
747 vs->read_handler_expect = ret;
752 static void vnc_write(VncState *vs, const void *data, size_t len)
754 buffer_reserve(&vs->output, len);
756 if (buffer_empty(&vs->output)) {
757 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
760 buffer_append(&vs->output, data, len);
763 static void vnc_write_s32(VncState *vs, int32_t value)
765 vnc_write_u32(vs, *(uint32_t *)&value);
768 static void vnc_write_u32(VncState *vs, uint32_t value)
770 uint8_t buf[4];
772 buf[0] = (value >> 24) & 0xFF;
773 buf[1] = (value >> 16) & 0xFF;
774 buf[2] = (value >> 8) & 0xFF;
775 buf[3] = value & 0xFF;
777 vnc_write(vs, buf, 4);
780 static void vnc_write_u16(VncState *vs, uint16_t value)
782 uint8_t buf[2];
784 buf[0] = (value >> 8) & 0xFF;
785 buf[1] = value & 0xFF;
787 vnc_write(vs, buf, 2);
790 static void vnc_write_u8(VncState *vs, uint8_t value)
792 vnc_write(vs, (char *)&value, 1);
795 static void vnc_flush(VncState *vs)
797 if (vs->output.offset)
798 vnc_client_write(vs);
801 static uint8_t read_u8(uint8_t *data, size_t offset)
803 return data[offset];
806 static uint16_t read_u16(uint8_t *data, size_t offset)
808 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
811 static int32_t read_s32(uint8_t *data, size_t offset)
813 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
814 (data[offset + 2] << 8) | data[offset + 3]);
817 static uint32_t read_u32(uint8_t *data, size_t offset)
819 return ((data[offset] << 24) | (data[offset + 1] << 16) |
820 (data[offset + 2] << 8) | data[offset + 3]);
823 #if CONFIG_VNC_TLS
824 static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
825 const void *data,
826 size_t len) {
827 struct VncState *vs = (struct VncState *)transport;
828 int ret;
830 retry:
831 ret = send(vs->csock, data, len, 0);
832 if (ret < 0) {
833 if (errno == EINTR)
834 goto retry;
835 return -1;
837 return ret;
841 static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
842 void *data,
843 size_t len) {
844 struct VncState *vs = (struct VncState *)transport;
845 int ret;
847 retry:
848 ret = recv(vs->csock, data, len, 0);
849 if (ret < 0) {
850 if (errno == EINTR)
851 goto retry;
852 return -1;
854 return ret;
856 #endif /* CONFIG_VNC_TLS */
858 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
862 static void check_pointer_type_change(VncState *vs, int absolute)
864 if (vs->has_pointer_type_change && vs->absolute != absolute) {
865 vnc_write_u8(vs, 0);
866 vnc_write_u8(vs, 0);
867 vnc_write_u16(vs, 1);
868 vnc_framebuffer_update(vs, absolute, 0,
869 vs->ds->width, vs->ds->height, -257);
870 vnc_flush(vs);
872 vs->absolute = absolute;
875 static void pointer_event(VncState *vs, int button_mask, int x, int y)
877 int buttons = 0;
878 int dz = 0;
880 if (button_mask & 0x01)
881 buttons |= MOUSE_EVENT_LBUTTON;
882 if (button_mask & 0x02)
883 buttons |= MOUSE_EVENT_MBUTTON;
884 if (button_mask & 0x04)
885 buttons |= MOUSE_EVENT_RBUTTON;
886 if (button_mask & 0x08)
887 dz = -1;
888 if (button_mask & 0x10)
889 dz = 1;
891 if (vs->absolute) {
892 kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
893 y * 0x7FFF / (vs->ds->height - 1),
894 dz, buttons);
895 } else if (vs->has_pointer_type_change) {
896 x -= 0x7FFF;
897 y -= 0x7FFF;
899 kbd_mouse_event(x, y, dz, buttons);
900 } else {
901 if (vs->last_x != -1)
902 kbd_mouse_event(x - vs->last_x,
903 y - vs->last_y,
904 dz, buttons);
905 vs->last_x = x;
906 vs->last_y = y;
909 check_pointer_type_change(vs, kbd_mouse_is_absolute());
912 static void reset_keys(VncState *vs)
914 int i;
915 for(i = 0; i < 256; i++) {
916 if (vs->modifiers_state[i]) {
917 if (i & 0x80)
918 kbd_put_keycode(0xe0);
919 kbd_put_keycode(i | 0x80);
920 vs->modifiers_state[i] = 0;
925 static void press_key(VncState *vs, int keysym)
927 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
928 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
931 static void do_key_event(VncState *vs, int down, uint32_t sym)
933 int keycode;
935 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
937 /* QEMU console switch */
938 switch(keycode) {
939 case 0x2a: /* Left Shift */
940 case 0x36: /* Right Shift */
941 case 0x1d: /* Left CTRL */
942 case 0x9d: /* Right CTRL */
943 case 0x38: /* Left ALT */
944 case 0xb8: /* Right ALT */
945 if (down)
946 vs->modifiers_state[keycode] = 1;
947 else
948 vs->modifiers_state[keycode] = 0;
949 break;
950 case 0x02 ... 0x0a: /* '1' to '9' keys */
951 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
952 /* Reset the modifiers sent to the current console */
953 reset_keys(vs);
954 console_select(keycode - 0x02);
955 return;
957 break;
958 case 0x3a: /* CapsLock */
959 case 0x45: /* NumLock */
960 if (!down)
961 vs->modifiers_state[keycode] ^= 1;
962 break;
965 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
966 /* If the numlock state needs to change then simulate an additional
967 keypress before sending this one. This will happen if the user
968 toggles numlock away from the VNC window.
970 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
971 if (!vs->modifiers_state[0x45]) {
972 vs->modifiers_state[0x45] = 1;
973 press_key(vs, 0xff7f);
975 } else {
976 if (vs->modifiers_state[0x45]) {
977 vs->modifiers_state[0x45] = 0;
978 press_key(vs, 0xff7f);
983 if (is_graphic_console()) {
984 if (keycode & 0x80)
985 kbd_put_keycode(0xe0);
986 if (down)
987 kbd_put_keycode(keycode & 0x7f);
988 else
989 kbd_put_keycode(keycode | 0x80);
990 } else {
991 /* QEMU console emulation */
992 if (down) {
993 switch (keycode) {
994 case 0x2a: /* Left Shift */
995 case 0x36: /* Right Shift */
996 case 0x1d: /* Left CTRL */
997 case 0x9d: /* Right CTRL */
998 case 0x38: /* Left ALT */
999 case 0xb8: /* Right ALT */
1000 break;
1001 case 0xc8:
1002 kbd_put_keysym(QEMU_KEY_UP);
1003 break;
1004 case 0xd0:
1005 kbd_put_keysym(QEMU_KEY_DOWN);
1006 break;
1007 case 0xcb:
1008 kbd_put_keysym(QEMU_KEY_LEFT);
1009 break;
1010 case 0xcd:
1011 kbd_put_keysym(QEMU_KEY_RIGHT);
1012 break;
1013 case 0xd3:
1014 kbd_put_keysym(QEMU_KEY_DELETE);
1015 break;
1016 case 0xc7:
1017 kbd_put_keysym(QEMU_KEY_HOME);
1018 break;
1019 case 0xcf:
1020 kbd_put_keysym(QEMU_KEY_END);
1021 break;
1022 case 0xc9:
1023 kbd_put_keysym(QEMU_KEY_PAGEUP);
1024 break;
1025 case 0xd1:
1026 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1027 break;
1028 default:
1029 kbd_put_keysym(sym);
1030 break;
1036 static void key_event(VncState *vs, int down, uint32_t sym)
1038 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1039 sym = sym - 'A' + 'a';
1040 do_key_event(vs, down, sym);
1043 static void framebuffer_update_request(VncState *vs, int incremental,
1044 int x_position, int y_position,
1045 int w, int h)
1047 if (x_position > vs->ds->width)
1048 x_position = vs->ds->width;
1049 if (y_position > vs->ds->height)
1050 y_position = vs->ds->height;
1051 if (x_position + w >= vs->ds->width)
1052 w = vs->ds->width - x_position;
1053 if (y_position + h >= vs->ds->height)
1054 h = vs->ds->height - y_position;
1056 int i;
1057 vs->need_update = 1;
1058 if (!incremental) {
1059 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1061 for (i = 0; i < h; i++) {
1062 vnc_set_bits(vs->dirty_row[y_position + i],
1063 (vs->ds->width / 16), VNC_DIRTY_WORDS);
1064 memset(old_row, 42, vs->ds->width * vs->depth);
1065 old_row += vs->ds->linesize;
1070 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1072 int i;
1074 vs->has_hextile = 0;
1075 vs->has_resize = 0;
1076 vs->has_pointer_type_change = 0;
1077 vs->absolute = -1;
1078 vs->ds->dpy_copy = NULL;
1080 for (i = n_encodings - 1; i >= 0; i--) {
1081 switch (encodings[i]) {
1082 case 0: /* Raw */
1083 vs->has_hextile = 0;
1084 break;
1085 case 1: /* CopyRect */
1086 vs->ds->dpy_copy = vnc_copy;
1087 break;
1088 case 5: /* Hextile */
1089 vs->has_hextile = 1;
1090 break;
1091 case -223: /* DesktopResize */
1092 vs->has_resize = 1;
1093 break;
1094 case -257:
1095 vs->has_pointer_type_change = 1;
1096 break;
1097 default:
1098 break;
1102 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1105 static int compute_nbits(unsigned int val)
1107 int n;
1108 n = 0;
1109 while (val != 0) {
1110 n++;
1111 val >>= 1;
1113 return n;
1116 static void set_pixel_format(VncState *vs,
1117 int bits_per_pixel, int depth,
1118 int big_endian_flag, int true_color_flag,
1119 int red_max, int green_max, int blue_max,
1120 int red_shift, int green_shift, int blue_shift)
1122 int host_big_endian_flag;
1124 #ifdef WORDS_BIGENDIAN
1125 host_big_endian_flag = 1;
1126 #else
1127 host_big_endian_flag = 0;
1128 #endif
1129 if (!true_color_flag) {
1130 fail:
1131 vnc_client_error(vs);
1132 return;
1134 if (bits_per_pixel == 32 &&
1135 host_big_endian_flag == big_endian_flag &&
1136 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1137 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1138 vs->depth = 4;
1139 vs->write_pixels = vnc_write_pixels_copy;
1140 vs->send_hextile_tile = send_hextile_tile_32;
1141 } else
1142 if (bits_per_pixel == 16 &&
1143 host_big_endian_flag == big_endian_flag &&
1144 red_max == 31 && green_max == 63 && blue_max == 31 &&
1145 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1146 vs->depth = 2;
1147 vs->write_pixels = vnc_write_pixels_copy;
1148 vs->send_hextile_tile = send_hextile_tile_16;
1149 } else
1150 if (bits_per_pixel == 8 &&
1151 red_max == 7 && green_max == 7 && blue_max == 3 &&
1152 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1153 vs->depth = 1;
1154 vs->write_pixels = vnc_write_pixels_copy;
1155 vs->send_hextile_tile = send_hextile_tile_8;
1156 } else
1158 /* generic and slower case */
1159 if (bits_per_pixel != 8 &&
1160 bits_per_pixel != 16 &&
1161 bits_per_pixel != 32)
1162 goto fail;
1163 vs->depth = 4;
1164 vs->red_shift = red_shift;
1165 vs->red_max = red_max;
1166 vs->red_shift1 = 24 - compute_nbits(red_max);
1167 vs->green_shift = green_shift;
1168 vs->green_max = green_max;
1169 vs->green_shift1 = 16 - compute_nbits(green_max);
1170 vs->blue_shift = blue_shift;
1171 vs->blue_max = blue_max;
1172 vs->blue_shift1 = 8 - compute_nbits(blue_max);
1173 vs->pix_bpp = bits_per_pixel / 8;
1174 vs->pix_big_endian = big_endian_flag;
1175 vs->write_pixels = vnc_write_pixels_generic;
1176 vs->send_hextile_tile = send_hextile_tile_generic;
1179 vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1180 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1181 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
1183 vga_hw_invalidate();
1184 vga_hw_update();
1187 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1189 int i;
1190 uint16_t limit;
1192 switch (data[0]) {
1193 case 0:
1194 if (len == 1)
1195 return 20;
1197 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1198 read_u8(data, 6), read_u8(data, 7),
1199 read_u16(data, 8), read_u16(data, 10),
1200 read_u16(data, 12), read_u8(data, 14),
1201 read_u8(data, 15), read_u8(data, 16));
1202 break;
1203 case 2:
1204 if (len == 1)
1205 return 4;
1207 if (len == 4)
1208 return 4 + (read_u16(data, 2) * 4);
1210 limit = read_u16(data, 2);
1211 for (i = 0; i < limit; i++) {
1212 int32_t val = read_s32(data, 4 + (i * 4));
1213 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1216 set_encodings(vs, (int32_t *)(data + 4), limit);
1217 break;
1218 case 3:
1219 if (len == 1)
1220 return 10;
1222 framebuffer_update_request(vs,
1223 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1224 read_u16(data, 6), read_u16(data, 8));
1225 break;
1226 case 4:
1227 if (len == 1)
1228 return 8;
1230 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1231 break;
1232 case 5:
1233 if (len == 1)
1234 return 6;
1236 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1237 break;
1238 case 6:
1239 if (len == 1)
1240 return 8;
1242 if (len == 8) {
1243 uint32_t dlen = read_u32(data, 4);
1244 if (dlen > 0)
1245 return 8 + dlen;
1248 client_cut_text(vs, read_u32(data, 4), data + 8);
1249 break;
1250 default:
1251 printf("Msg: %d\n", data[0]);
1252 vnc_client_error(vs);
1253 break;
1256 vnc_read_when(vs, protocol_client_msg, 1);
1257 return 0;
1260 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1262 char pad[3] = { 0, 0, 0 };
1263 char buf[1024];
1264 int size;
1265 char prog[30] = "QEMU";
1267 vs->width = vs->ds->width;
1268 vs->height = vs->ds->height;
1269 vnc_write_u16(vs, vs->ds->width);
1270 vnc_write_u16(vs, vs->ds->height);
1272 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1273 vnc_write_u8(vs, vs->depth * 8); /* depth */
1274 #ifdef WORDS_BIGENDIAN
1275 vnc_write_u8(vs, 1); /* big-endian-flag */
1276 #else
1277 vnc_write_u8(vs, 0); /* big-endian-flag */
1278 #endif
1279 vnc_write_u8(vs, 1); /* true-color-flag */
1280 if (vs->depth == 4) {
1281 vnc_write_u16(vs, 0xFF); /* red-max */
1282 vnc_write_u16(vs, 0xFF); /* green-max */
1283 vnc_write_u16(vs, 0xFF); /* blue-max */
1284 vnc_write_u8(vs, 16); /* red-shift */
1285 vnc_write_u8(vs, 8); /* green-shift */
1286 vnc_write_u8(vs, 0); /* blue-shift */
1287 vs->send_hextile_tile = send_hextile_tile_32;
1288 } else if (vs->depth == 2) {
1289 vnc_write_u16(vs, 31); /* red-max */
1290 vnc_write_u16(vs, 63); /* green-max */
1291 vnc_write_u16(vs, 31); /* blue-max */
1292 vnc_write_u8(vs, 11); /* red-shift */
1293 vnc_write_u8(vs, 5); /* green-shift */
1294 vnc_write_u8(vs, 0); /* blue-shift */
1295 vs->send_hextile_tile = send_hextile_tile_16;
1296 } else if (vs->depth == 1) {
1297 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1298 vnc_write_u16(vs, 7); /* red-max */
1299 vnc_write_u16(vs, 7); /* green-max */
1300 vnc_write_u16(vs, 3); /* blue-max */
1301 vnc_write_u8(vs, 5); /* red-shift */
1302 vnc_write_u8(vs, 2); /* green-shift */
1303 vnc_write_u8(vs, 0); /* blue-shift */
1304 vs->send_hextile_tile = send_hextile_tile_8;
1306 vs->write_pixels = vnc_write_pixels_copy;
1308 vnc_write(vs, pad, 3); /* padding */
1310 decorate_application_name((char *)prog, sizeof prog);
1312 if (qemu_name)
1313 size = snprintf(buf, sizeof(buf), "%s (%s)", prog, qemu_name);
1314 else
1315 size = snprintf(buf, sizeof(buf), "%s", prog);
1317 vnc_write_u32(vs, size);
1318 vnc_write(vs, buf, size);
1319 vnc_flush(vs);
1321 vnc_read_when(vs, protocol_client_msg, 1);
1323 return 0;
1326 static void make_challenge(VncState *vs)
1328 int i;
1330 srand(time(NULL)+getpid()+getpid()*987654+rand());
1332 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1333 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1336 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1338 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1339 int i, j, pwlen;
1340 unsigned char key[8];
1342 if (!vs->password || !vs->password[0]) {
1343 VNC_DEBUG("No password configured on server");
1344 vnc_write_u32(vs, 1); /* Reject auth */
1345 if (vs->minor >= 8) {
1346 static const char err[] = "Authentication failed";
1347 vnc_write_u32(vs, sizeof(err));
1348 vnc_write(vs, err, sizeof(err));
1350 vnc_flush(vs);
1351 vnc_client_error(vs);
1352 return 0;
1355 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1357 /* Calculate the expected challenge response */
1358 pwlen = strlen(vs->password);
1359 for (i=0; i<sizeof(key); i++)
1360 key[i] = i<pwlen ? vs->password[i] : 0;
1361 deskey(key, EN0);
1362 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1363 des(response+j, response+j);
1365 /* Compare expected vs actual challenge response */
1366 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1367 VNC_DEBUG("Client challenge reponse did not match\n");
1368 vnc_write_u32(vs, 1); /* Reject auth */
1369 if (vs->minor >= 8) {
1370 static const char err[] = "Authentication failed";
1371 vnc_write_u32(vs, sizeof(err));
1372 vnc_write(vs, err, sizeof(err));
1374 vnc_flush(vs);
1375 vnc_client_error(vs);
1376 } else {
1377 VNC_DEBUG("Accepting VNC challenge response\n");
1378 vnc_write_u32(vs, 0); /* Accept auth */
1379 vnc_flush(vs);
1381 vnc_read_when(vs, protocol_client_init, 1);
1383 return 0;
1386 static int start_auth_vnc(VncState *vs)
1388 make_challenge(vs);
1389 /* Send client a 'random' challenge */
1390 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1391 vnc_flush(vs);
1393 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1394 return 0;
1398 #if CONFIG_VNC_TLS
1399 #define DH_BITS 1024
1400 static gnutls_dh_params_t dh_params;
1402 static int vnc_tls_initialize(void)
1404 static int tlsinitialized = 0;
1406 if (tlsinitialized)
1407 return 1;
1409 if (gnutls_global_init () < 0)
1410 return 0;
1412 /* XXX ought to re-generate diffie-hellmen params periodically */
1413 if (gnutls_dh_params_init (&dh_params) < 0)
1414 return 0;
1415 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1416 return 0;
1418 #if _VNC_DEBUG == 2
1419 gnutls_global_set_log_level(10);
1420 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1421 #endif
1423 tlsinitialized = 1;
1425 return 1;
1428 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1430 gnutls_anon_server_credentials anon_cred;
1431 int ret;
1433 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1434 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1435 return NULL;
1438 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1440 return anon_cred;
1444 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1446 gnutls_certificate_credentials_t x509_cred;
1447 int ret;
1449 if (!vs->x509cacert) {
1450 VNC_DEBUG("No CA x509 certificate specified\n");
1451 return NULL;
1453 if (!vs->x509cert) {
1454 VNC_DEBUG("No server x509 certificate specified\n");
1455 return NULL;
1457 if (!vs->x509key) {
1458 VNC_DEBUG("No server private key specified\n");
1459 return NULL;
1462 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1463 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1464 return NULL;
1466 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1467 vs->x509cacert,
1468 GNUTLS_X509_FMT_PEM)) < 0) {
1469 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1470 gnutls_certificate_free_credentials(x509_cred);
1471 return NULL;
1474 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1475 vs->x509cert,
1476 vs->x509key,
1477 GNUTLS_X509_FMT_PEM)) < 0) {
1478 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1479 gnutls_certificate_free_credentials(x509_cred);
1480 return NULL;
1483 if (vs->x509cacrl) {
1484 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1485 vs->x509cacrl,
1486 GNUTLS_X509_FMT_PEM)) < 0) {
1487 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1488 gnutls_certificate_free_credentials(x509_cred);
1489 return NULL;
1493 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1495 return x509_cred;
1498 static int vnc_validate_certificate(struct VncState *vs)
1500 int ret;
1501 unsigned int status;
1502 const gnutls_datum_t *certs;
1503 unsigned int nCerts, i;
1504 time_t now;
1506 VNC_DEBUG("Validating client certificate\n");
1507 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1508 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1509 return -1;
1512 if ((now = time(NULL)) == ((time_t)-1)) {
1513 return -1;
1516 if (status != 0) {
1517 if (status & GNUTLS_CERT_INVALID)
1518 VNC_DEBUG("The certificate is not trusted.\n");
1520 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1521 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1523 if (status & GNUTLS_CERT_REVOKED)
1524 VNC_DEBUG("The certificate has been revoked.\n");
1526 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1527 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1529 return -1;
1530 } else {
1531 VNC_DEBUG("Certificate is valid!\n");
1534 /* Only support x509 for now */
1535 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1536 return -1;
1538 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1539 return -1;
1541 for (i = 0 ; i < nCerts ; i++) {
1542 gnutls_x509_crt_t cert;
1543 VNC_DEBUG ("Checking certificate chain %d\n", i);
1544 if (gnutls_x509_crt_init (&cert) < 0)
1545 return -1;
1547 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1548 gnutls_x509_crt_deinit (cert);
1549 return -1;
1552 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1553 VNC_DEBUG("The certificate has expired\n");
1554 gnutls_x509_crt_deinit (cert);
1555 return -1;
1558 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1559 VNC_DEBUG("The certificate is not yet activated\n");
1560 gnutls_x509_crt_deinit (cert);
1561 return -1;
1564 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1565 VNC_DEBUG("The certificate is not yet activated\n");
1566 gnutls_x509_crt_deinit (cert);
1567 return -1;
1570 gnutls_x509_crt_deinit (cert);
1573 return 0;
1577 static int start_auth_vencrypt_subauth(VncState *vs)
1579 switch (vs->subauth) {
1580 case VNC_AUTH_VENCRYPT_TLSNONE:
1581 case VNC_AUTH_VENCRYPT_X509NONE:
1582 VNC_DEBUG("Accept TLS auth none\n");
1583 vnc_write_u32(vs, 0); /* Accept auth completion */
1584 vnc_read_when(vs, protocol_client_init, 1);
1585 break;
1587 case VNC_AUTH_VENCRYPT_TLSVNC:
1588 case VNC_AUTH_VENCRYPT_X509VNC:
1589 VNC_DEBUG("Start TLS auth VNC\n");
1590 return start_auth_vnc(vs);
1592 default: /* Should not be possible, but just in case */
1593 VNC_DEBUG("Reject auth %d\n", vs->auth);
1594 vnc_write_u8(vs, 1);
1595 if (vs->minor >= 8) {
1596 static const char err[] = "Unsupported authentication type";
1597 vnc_write_u32(vs, sizeof(err));
1598 vnc_write(vs, err, sizeof(err));
1600 vnc_client_error(vs);
1603 return 0;
1606 static void vnc_handshake_io(void *opaque);
1608 static int vnc_continue_handshake(struct VncState *vs) {
1609 int ret;
1611 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1612 if (!gnutls_error_is_fatal(ret)) {
1613 VNC_DEBUG("Handshake interrupted (blocking)\n");
1614 if (!gnutls_record_get_direction(vs->tls_session))
1615 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1616 else
1617 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1618 return 0;
1620 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1621 vnc_client_error(vs);
1622 return -1;
1625 if (vs->x509verify) {
1626 if (vnc_validate_certificate(vs) < 0) {
1627 VNC_DEBUG("Client verification failed\n");
1628 vnc_client_error(vs);
1629 return -1;
1630 } else {
1631 VNC_DEBUG("Client verification passed\n");
1635 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1636 vs->wiremode = VNC_WIREMODE_TLS;
1637 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1639 return start_auth_vencrypt_subauth(vs);
1642 static void vnc_handshake_io(void *opaque) {
1643 struct VncState *vs = (struct VncState *)opaque;
1645 VNC_DEBUG("Handshake IO continue\n");
1646 vnc_continue_handshake(vs);
1649 #define NEED_X509_AUTH(vs) \
1650 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1651 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1652 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1655 static int vnc_start_tls(struct VncState *vs) {
1656 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1657 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1658 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1659 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1661 VNC_DEBUG("Do TLS setup\n");
1662 if (vnc_tls_initialize() < 0) {
1663 VNC_DEBUG("Failed to init TLS\n");
1664 vnc_client_error(vs);
1665 return -1;
1667 if (vs->tls_session == NULL) {
1668 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1669 vnc_client_error(vs);
1670 return -1;
1673 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1674 gnutls_deinit(vs->tls_session);
1675 vs->tls_session = NULL;
1676 vnc_client_error(vs);
1677 return -1;
1680 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1681 gnutls_deinit(vs->tls_session);
1682 vs->tls_session = NULL;
1683 vnc_client_error(vs);
1684 return -1;
1687 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1688 gnutls_deinit(vs->tls_session);
1689 vs->tls_session = NULL;
1690 vnc_client_error(vs);
1691 return -1;
1694 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1695 gnutls_deinit(vs->tls_session);
1696 vs->tls_session = NULL;
1697 vnc_client_error(vs);
1698 return -1;
1701 if (NEED_X509_AUTH(vs)) {
1702 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1703 if (!x509_cred) {
1704 gnutls_deinit(vs->tls_session);
1705 vs->tls_session = NULL;
1706 vnc_client_error(vs);
1707 return -1;
1709 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1710 gnutls_deinit(vs->tls_session);
1711 vs->tls_session = NULL;
1712 gnutls_certificate_free_credentials(x509_cred);
1713 vnc_client_error(vs);
1714 return -1;
1716 if (vs->x509verify) {
1717 VNC_DEBUG("Requesting a client certificate\n");
1718 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1721 } else {
1722 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1723 if (!anon_cred) {
1724 gnutls_deinit(vs->tls_session);
1725 vs->tls_session = NULL;
1726 vnc_client_error(vs);
1727 return -1;
1729 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1730 gnutls_deinit(vs->tls_session);
1731 vs->tls_session = NULL;
1732 gnutls_anon_free_server_credentials(anon_cred);
1733 vnc_client_error(vs);
1734 return -1;
1738 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1739 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1740 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1743 VNC_DEBUG("Start TLS handshake process\n");
1744 return vnc_continue_handshake(vs);
1747 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
1749 int auth = read_u32(data, 0);
1751 if (auth != vs->subauth) {
1752 VNC_DEBUG("Rejecting auth %d\n", auth);
1753 vnc_write_u8(vs, 0); /* Reject auth */
1754 vnc_flush(vs);
1755 vnc_client_error(vs);
1756 } else {
1757 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1758 vnc_write_u8(vs, 1); /* Accept auth */
1759 vnc_flush(vs);
1761 if (vnc_start_tls(vs) < 0) {
1762 VNC_DEBUG("Failed to complete TLS\n");
1763 return 0;
1766 if (vs->wiremode == VNC_WIREMODE_TLS) {
1767 VNC_DEBUG("Starting VeNCrypt subauth\n");
1768 return start_auth_vencrypt_subauth(vs);
1769 } else {
1770 VNC_DEBUG("TLS handshake blocked\n");
1771 return 0;
1774 return 0;
1777 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
1779 if (data[0] != 0 ||
1780 data[1] != 2) {
1781 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1782 vnc_write_u8(vs, 1); /* Reject version */
1783 vnc_flush(vs);
1784 vnc_client_error(vs);
1785 } else {
1786 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1787 vnc_write_u8(vs, 0); /* Accept version */
1788 vnc_write_u8(vs, 1); /* Number of sub-auths */
1789 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1790 vnc_flush(vs);
1791 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1793 return 0;
1796 static int start_auth_vencrypt(VncState *vs)
1798 /* Send VeNCrypt version 0.2 */
1799 vnc_write_u8(vs, 0);
1800 vnc_write_u8(vs, 2);
1802 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1803 return 0;
1805 #endif /* CONFIG_VNC_TLS */
1807 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1809 /* We only advertise 1 auth scheme at a time, so client
1810 * must pick the one we sent. Verify this */
1811 if (data[0] != vs->auth) { /* Reject auth */
1812 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1813 vnc_write_u32(vs, 1);
1814 if (vs->minor >= 8) {
1815 static const char err[] = "Authentication failed";
1816 vnc_write_u32(vs, sizeof(err));
1817 vnc_write(vs, err, sizeof(err));
1819 vnc_client_error(vs);
1820 } else { /* Accept requested auth */
1821 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1822 switch (vs->auth) {
1823 case VNC_AUTH_NONE:
1824 VNC_DEBUG("Accept auth none\n");
1825 if (vs->minor >= 8) {
1826 vnc_write_u32(vs, 0); /* Accept auth completion */
1827 vnc_flush(vs);
1829 vnc_read_when(vs, protocol_client_init, 1);
1830 break;
1832 case VNC_AUTH_VNC:
1833 VNC_DEBUG("Start VNC auth\n");
1834 return start_auth_vnc(vs);
1836 #if CONFIG_VNC_TLS
1837 case VNC_AUTH_VENCRYPT:
1838 VNC_DEBUG("Accept VeNCrypt auth\n");;
1839 return start_auth_vencrypt(vs);
1840 #endif /* CONFIG_VNC_TLS */
1842 default: /* Should not be possible, but just in case */
1843 VNC_DEBUG("Reject auth %d\n", vs->auth);
1844 vnc_write_u8(vs, 1);
1845 if (vs->minor >= 8) {
1846 static const char err[] = "Authentication failed";
1847 vnc_write_u32(vs, sizeof(err));
1848 vnc_write(vs, err, sizeof(err));
1850 vnc_client_error(vs);
1853 return 0;
1856 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1858 char local[13];
1860 memcpy(local, version, 12);
1861 local[12] = 0;
1863 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1864 VNC_DEBUG("Malformed protocol version %s\n", local);
1865 vnc_client_error(vs);
1866 return 0;
1868 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1869 if (vs->major != 3 ||
1870 (vs->minor != 3 &&
1871 vs->minor != 4 &&
1872 vs->minor != 5 &&
1873 vs->minor != 7 &&
1874 vs->minor != 8)) {
1875 VNC_DEBUG("Unsupported client version\n");
1876 vnc_write_u32(vs, VNC_AUTH_INVALID);
1877 vnc_flush(vs);
1878 vnc_client_error(vs);
1879 return 0;
1881 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1882 * as equivalent to v3.3 by servers
1884 if (vs->minor == 4 || vs->minor == 5)
1885 vs->minor = 3;
1887 if (vs->minor == 3) {
1888 if (vs->auth == VNC_AUTH_NONE) {
1889 VNC_DEBUG("Tell client auth none\n");
1890 vnc_write_u32(vs, vs->auth);
1891 vnc_flush(vs);
1892 vnc_read_when(vs, protocol_client_init, 1);
1893 } else if (vs->auth == VNC_AUTH_VNC) {
1894 VNC_DEBUG("Tell client VNC auth\n");
1895 vnc_write_u32(vs, vs->auth);
1896 vnc_flush(vs);
1897 start_auth_vnc(vs);
1898 } else {
1899 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1900 vnc_write_u32(vs, VNC_AUTH_INVALID);
1901 vnc_flush(vs);
1902 vnc_client_error(vs);
1904 } else {
1905 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1906 vnc_write_u8(vs, 1); /* num auth */
1907 vnc_write_u8(vs, vs->auth);
1908 vnc_read_when(vs, protocol_client_auth, 1);
1909 vnc_flush(vs);
1912 return 0;
1915 static void vnc_connect(VncState *vs)
1917 VNC_DEBUG("New client on socket %d\n", vs->csock);
1918 socket_set_nonblock(vs->csock);
1919 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1920 vnc_write(vs, "RFB 003.008\n", 12);
1921 vnc_flush(vs);
1922 vnc_read_when(vs, protocol_version, 12);
1923 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1924 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1925 vs->has_resize = 0;
1926 vs->has_hextile = 0;
1927 vs->ds->dpy_copy = NULL;
1928 vnc_update_client(vs);
1931 static void vnc_listen_read(void *opaque)
1933 VncState *vs = opaque;
1934 struct sockaddr_in addr;
1935 socklen_t addrlen = sizeof(addr);
1937 /* Catch-up */
1938 vga_hw_update();
1940 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1941 if (vs->csock != -1) {
1942 vnc_connect(vs);
1946 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1948 void vnc_display_init(DisplayState *ds)
1950 VncState *vs;
1952 vs = qemu_mallocz(sizeof(VncState));
1953 if (!vs)
1954 exit(1);
1956 ds->opaque = vs;
1957 vnc_state = vs;
1958 vs->display = NULL;
1959 vs->password = NULL;
1961 vs->lsock = -1;
1962 vs->csock = -1;
1963 vs->depth = 4;
1964 vs->last_x = -1;
1965 vs->last_y = -1;
1967 vs->ds = ds;
1969 if (!keyboard_layout)
1970 keyboard_layout = "en-us";
1972 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1973 if (!vs->kbd_layout)
1974 exit(1);
1976 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
1978 vs->ds->data = NULL;
1979 vs->ds->dpy_update = vnc_dpy_update;
1980 vs->ds->dpy_resize = vnc_dpy_resize;
1981 vs->ds->dpy_refresh = NULL;
1983 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1985 vnc_dpy_resize(vs->ds, 640, 400);
1988 #if CONFIG_VNC_TLS
1989 static int vnc_set_x509_credential(VncState *vs,
1990 const char *certdir,
1991 const char *filename,
1992 char **cred,
1993 int ignoreMissing)
1995 struct stat sb;
1997 if (*cred) {
1998 qemu_free(*cred);
1999 *cred = NULL;
2002 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
2003 return -1;
2005 strcpy(*cred, certdir);
2006 strcat(*cred, "/");
2007 strcat(*cred, filename);
2009 VNC_DEBUG("Check %s\n", *cred);
2010 if (stat(*cred, &sb) < 0) {
2011 qemu_free(*cred);
2012 *cred = NULL;
2013 if (ignoreMissing && errno == ENOENT)
2014 return 0;
2015 return -1;
2018 return 0;
2021 static int vnc_set_x509_credential_dir(VncState *vs,
2022 const char *certdir)
2024 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2025 goto cleanup;
2026 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2027 goto cleanup;
2028 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2029 goto cleanup;
2030 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2031 goto cleanup;
2033 return 0;
2035 cleanup:
2036 qemu_free(vs->x509cacert);
2037 qemu_free(vs->x509cacrl);
2038 qemu_free(vs->x509cert);
2039 qemu_free(vs->x509key);
2040 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2041 return -1;
2043 #endif /* CONFIG_VNC_TLS */
2045 void vnc_display_close(DisplayState *ds)
2047 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2049 if (vs->display) {
2050 qemu_free(vs->display);
2051 vs->display = NULL;
2053 if (vs->lsock != -1) {
2054 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2055 close(vs->lsock);
2056 vs->lsock = -1;
2058 if (vs->csock != -1) {
2059 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2060 closesocket(vs->csock);
2061 vs->csock = -1;
2062 buffer_reset(&vs->input);
2063 buffer_reset(&vs->output);
2064 vs->need_update = 0;
2065 #if CONFIG_VNC_TLS
2066 if (vs->tls_session) {
2067 gnutls_deinit(vs->tls_session);
2068 vs->tls_session = NULL;
2070 vs->wiremode = VNC_WIREMODE_CLEAR;
2071 #endif /* CONFIG_VNC_TLS */
2073 vs->auth = VNC_AUTH_INVALID;
2074 #if CONFIG_VNC_TLS
2075 vs->subauth = VNC_AUTH_INVALID;
2076 vs->x509verify = 0;
2077 #endif
2080 int vnc_display_password(DisplayState *ds, const char *password)
2082 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2084 if (vs->password) {
2085 qemu_free(vs->password);
2086 vs->password = NULL;
2088 if (password && password[0]) {
2089 if (!(vs->password = qemu_strdup(password)))
2090 return -1;
2093 return 0;
2096 int vnc_display_open(DisplayState *ds, const char *display)
2098 struct sockaddr *addr;
2099 struct sockaddr_in iaddr;
2100 #ifndef _WIN32
2101 struct sockaddr_un uaddr;
2102 const char *p;
2103 #endif
2104 int reuse_addr, ret;
2105 socklen_t addrlen;
2106 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2107 const char *options;
2108 int password = 0;
2109 int reverse = 0;
2110 #if CONFIG_VNC_TLS
2111 int tls = 0, x509 = 0;
2112 #endif
2114 vnc_display_close(ds);
2115 if (strcmp(display, "none") == 0)
2116 return 0;
2118 if (!(vs->display = strdup(display)))
2119 return -1;
2121 options = display;
2122 while ((options = strchr(options, ','))) {
2123 options++;
2124 if (strncmp(options, "password", 8) == 0) {
2125 password = 1; /* Require password auth */
2126 } else if (strncmp(options, "reverse", 7) == 0) {
2127 reverse = 1;
2128 #if CONFIG_VNC_TLS
2129 } else if (strncmp(options, "tls", 3) == 0) {
2130 tls = 1; /* Require TLS */
2131 } else if (strncmp(options, "x509", 4) == 0) {
2132 char *start, *end;
2133 x509 = 1; /* Require x509 certificates */
2134 if (strncmp(options, "x509verify", 10) == 0)
2135 vs->x509verify = 1; /* ...and verify client certs */
2137 /* Now check for 'x509=/some/path' postfix
2138 * and use that to setup x509 certificate/key paths */
2139 start = strchr(options, '=');
2140 end = strchr(options, ',');
2141 if (start && (!end || (start < end))) {
2142 int len = end ? end-(start+1) : strlen(start+1);
2143 char *path = qemu_malloc(len+1);
2144 strncpy(path, start+1, len);
2145 path[len] = '\0';
2146 VNC_DEBUG("Trying certificate path '%s'\n", path);
2147 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2148 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2149 qemu_free(path);
2150 qemu_free(vs->display);
2151 vs->display = NULL;
2152 return -1;
2154 qemu_free(path);
2155 } else {
2156 fprintf(stderr, "No certificate path provided\n");
2157 qemu_free(vs->display);
2158 vs->display = NULL;
2159 return -1;
2161 #endif
2165 if (password) {
2166 #if CONFIG_VNC_TLS
2167 if (tls) {
2168 vs->auth = VNC_AUTH_VENCRYPT;
2169 if (x509) {
2170 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2171 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2172 } else {
2173 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2174 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2176 } else {
2177 #endif
2178 VNC_DEBUG("Initializing VNC server with password auth\n");
2179 vs->auth = VNC_AUTH_VNC;
2180 #if CONFIG_VNC_TLS
2181 vs->subauth = VNC_AUTH_INVALID;
2183 #endif
2184 } else {
2185 #if CONFIG_VNC_TLS
2186 if (tls) {
2187 vs->auth = VNC_AUTH_VENCRYPT;
2188 if (x509) {
2189 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2190 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2191 } else {
2192 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2193 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2195 } else {
2196 #endif
2197 VNC_DEBUG("Initializing VNC server with no auth\n");
2198 vs->auth = VNC_AUTH_NONE;
2199 #if CONFIG_VNC_TLS
2200 vs->subauth = VNC_AUTH_INVALID;
2202 #endif
2204 #ifndef _WIN32
2205 if (strstart(display, "unix:", &p)) {
2206 addr = (struct sockaddr *)&uaddr;
2207 addrlen = sizeof(uaddr);
2209 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2210 if (vs->lsock == -1) {
2211 fprintf(stderr, "Could not create socket\n");
2212 free(vs->display);
2213 vs->display = NULL;
2214 return -1;
2217 uaddr.sun_family = AF_UNIX;
2218 memset(uaddr.sun_path, 0, 108);
2219 snprintf(uaddr.sun_path, 108, "%s", p);
2221 if (!reverse) {
2222 unlink(uaddr.sun_path);
2224 } else
2225 #endif
2227 addr = (struct sockaddr *)&iaddr;
2228 addrlen = sizeof(iaddr);
2230 if (parse_host_port(&iaddr, display) < 0) {
2231 fprintf(stderr, "Could not parse VNC address\n");
2232 free(vs->display);
2233 vs->display = NULL;
2234 return -1;
2237 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900));
2239 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2240 if (vs->lsock == -1) {
2241 fprintf(stderr, "Could not create socket\n");
2242 free(vs->display);
2243 vs->display = NULL;
2244 return -1;
2247 reuse_addr = 1;
2248 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2249 (const char *)&reuse_addr, sizeof(reuse_addr));
2250 if (ret == -1) {
2251 fprintf(stderr, "setsockopt() failed\n");
2252 close(vs->lsock);
2253 vs->lsock = -1;
2254 free(vs->display);
2255 vs->display = NULL;
2256 return -1;
2260 if (reverse) {
2261 if (connect(vs->lsock, addr, addrlen) == -1) {
2262 fprintf(stderr, "Connection to VNC client failed\n");
2263 close(vs->lsock);
2264 vs->lsock = -1;
2265 free(vs->display);
2266 vs->display = NULL;
2267 return -1;
2268 } else {
2269 vs->csock = vs->lsock;
2270 vs->lsock = -1;
2271 vnc_connect(vs);
2272 return 0;
2276 if (bind(vs->lsock, addr, addrlen) == -1) {
2277 fprintf(stderr, "bind() failed\n");
2278 close(vs->lsock);
2279 vs->lsock = -1;
2280 free(vs->display);
2281 vs->display = NULL;
2282 return -1;
2285 if (listen(vs->lsock, 1) == -1) {
2286 fprintf(stderr, "listen() failed\n");
2287 close(vs->lsock);
2288 vs->lsock = -1;
2289 free(vs->display);
2290 vs->display = NULL;
2291 return -1;
2294 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);