kvm: qemu: ftruncate() is not supported by hugetlbfs on older hosts
[kvm-userspace.git] / qemu / vnc.c
blob7e69b49867a3df7215452d8d9d75fdce3e49e722
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 && (last_errno == EINTR || last_errno == EAGAIN))
637 return 0;
639 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
640 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
641 closesocket(vs->csock);
642 vs->csock = -1;
643 buffer_reset(&vs->input);
644 buffer_reset(&vs->output);
645 vs->need_update = 0;
646 #if CONFIG_VNC_TLS
647 if (vs->tls_session) {
648 gnutls_deinit(vs->tls_session);
649 vs->tls_session = NULL;
651 vs->wiremode = VNC_WIREMODE_CLEAR;
652 #endif /* CONFIG_VNC_TLS */
653 return 0;
655 return ret;
658 static void vnc_client_error(VncState *vs)
660 vnc_client_io_error(vs, -1, EINVAL);
663 static void vnc_client_write(void *opaque)
665 long ret;
666 VncState *vs = opaque;
668 #if CONFIG_VNC_TLS
669 if (vs->tls_session) {
670 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
671 if (ret < 0) {
672 if (ret == GNUTLS_E_AGAIN)
673 errno = EAGAIN;
674 else
675 errno = EIO;
676 ret = -1;
678 } else
679 #endif /* CONFIG_VNC_TLS */
680 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
681 ret = vnc_client_io_error(vs, ret, socket_error());
682 if (!ret)
683 return;
685 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
686 vs->output.offset -= ret;
688 if (vs->output.offset == 0) {
689 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
693 static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
695 vs->read_handler = func;
696 vs->read_handler_expect = expecting;
699 static void vnc_client_read(void *opaque)
701 VncState *vs = opaque;
702 long ret;
704 buffer_reserve(&vs->input, 4096);
706 #if CONFIG_VNC_TLS
707 if (vs->tls_session) {
708 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
709 if (ret < 0) {
710 if (ret == GNUTLS_E_AGAIN)
711 errno = EAGAIN;
712 else
713 errno = EIO;
714 ret = -1;
716 } else
717 #endif /* CONFIG_VNC_TLS */
718 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
719 ret = vnc_client_io_error(vs, ret, socket_error());
720 if (!ret)
721 return;
723 vs->input.offset += ret;
725 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
726 size_t len = vs->read_handler_expect;
727 int ret;
729 ret = vs->read_handler(vs, vs->input.buffer, len);
730 if (vs->csock == -1)
731 return;
733 if (!ret) {
734 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
735 vs->input.offset -= len;
736 } else {
737 vs->read_handler_expect = ret;
742 static void vnc_write(VncState *vs, const void *data, size_t len)
744 buffer_reserve(&vs->output, len);
746 if (buffer_empty(&vs->output)) {
747 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
750 buffer_append(&vs->output, data, len);
753 static void vnc_write_s32(VncState *vs, int32_t value)
755 vnc_write_u32(vs, *(uint32_t *)&value);
758 static void vnc_write_u32(VncState *vs, uint32_t value)
760 uint8_t buf[4];
762 buf[0] = (value >> 24) & 0xFF;
763 buf[1] = (value >> 16) & 0xFF;
764 buf[2] = (value >> 8) & 0xFF;
765 buf[3] = value & 0xFF;
767 vnc_write(vs, buf, 4);
770 static void vnc_write_u16(VncState *vs, uint16_t value)
772 uint8_t buf[2];
774 buf[0] = (value >> 8) & 0xFF;
775 buf[1] = value & 0xFF;
777 vnc_write(vs, buf, 2);
780 static void vnc_write_u8(VncState *vs, uint8_t value)
782 vnc_write(vs, (char *)&value, 1);
785 static void vnc_flush(VncState *vs)
787 if (vs->output.offset)
788 vnc_client_write(vs);
791 static uint8_t read_u8(uint8_t *data, size_t offset)
793 return data[offset];
796 static uint16_t read_u16(uint8_t *data, size_t offset)
798 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
801 static int32_t read_s32(uint8_t *data, size_t offset)
803 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
804 (data[offset + 2] << 8) | data[offset + 3]);
807 static uint32_t read_u32(uint8_t *data, size_t offset)
809 return ((data[offset] << 24) | (data[offset + 1] << 16) |
810 (data[offset + 2] << 8) | data[offset + 3]);
813 #if CONFIG_VNC_TLS
814 static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
815 const void *data,
816 size_t len) {
817 struct VncState *vs = (struct VncState *)transport;
818 int ret;
820 retry:
821 ret = send(vs->csock, data, len, 0);
822 if (ret < 0) {
823 if (errno == EINTR)
824 goto retry;
825 return -1;
827 return ret;
831 static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
832 void *data,
833 size_t len) {
834 struct VncState *vs = (struct VncState *)transport;
835 int ret;
837 retry:
838 ret = recv(vs->csock, data, len, 0);
839 if (ret < 0) {
840 if (errno == EINTR)
841 goto retry;
842 return -1;
844 return ret;
846 #endif /* CONFIG_VNC_TLS */
848 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
852 static void check_pointer_type_change(VncState *vs, int absolute)
854 if (vs->has_pointer_type_change && vs->absolute != absolute) {
855 vnc_write_u8(vs, 0);
856 vnc_write_u8(vs, 0);
857 vnc_write_u16(vs, 1);
858 vnc_framebuffer_update(vs, absolute, 0,
859 vs->ds->width, vs->ds->height, -257);
860 vnc_flush(vs);
862 vs->absolute = absolute;
865 static void pointer_event(VncState *vs, int button_mask, int x, int y)
867 int buttons = 0;
868 int dz = 0;
870 if (button_mask & 0x01)
871 buttons |= MOUSE_EVENT_LBUTTON;
872 if (button_mask & 0x02)
873 buttons |= MOUSE_EVENT_MBUTTON;
874 if (button_mask & 0x04)
875 buttons |= MOUSE_EVENT_RBUTTON;
876 if (button_mask & 0x08)
877 dz = -1;
878 if (button_mask & 0x10)
879 dz = 1;
881 if (vs->absolute) {
882 kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
883 y * 0x7FFF / (vs->ds->height - 1),
884 dz, buttons);
885 } else if (vs->has_pointer_type_change) {
886 x -= 0x7FFF;
887 y -= 0x7FFF;
889 kbd_mouse_event(x, y, dz, buttons);
890 } else {
891 if (vs->last_x != -1)
892 kbd_mouse_event(x - vs->last_x,
893 y - vs->last_y,
894 dz, buttons);
895 vs->last_x = x;
896 vs->last_y = y;
899 check_pointer_type_change(vs, kbd_mouse_is_absolute());
902 static void reset_keys(VncState *vs)
904 int i;
905 for(i = 0; i < 256; i++) {
906 if (vs->modifiers_state[i]) {
907 if (i & 0x80)
908 kbd_put_keycode(0xe0);
909 kbd_put_keycode(i | 0x80);
910 vs->modifiers_state[i] = 0;
915 static void press_key(VncState *vs, int keysym)
917 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
918 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
921 static void do_key_event(VncState *vs, int down, uint32_t sym)
923 int keycode;
925 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
927 /* QEMU console switch */
928 switch(keycode) {
929 case 0x2a: /* Left Shift */
930 case 0x36: /* Right Shift */
931 case 0x1d: /* Left CTRL */
932 case 0x9d: /* Right CTRL */
933 case 0x38: /* Left ALT */
934 case 0xb8: /* Right ALT */
935 if (down)
936 vs->modifiers_state[keycode] = 1;
937 else
938 vs->modifiers_state[keycode] = 0;
939 break;
940 case 0x02 ... 0x0a: /* '1' to '9' keys */
941 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
942 /* Reset the modifiers sent to the current console */
943 reset_keys(vs);
944 console_select(keycode - 0x02);
945 return;
947 break;
948 case 0x3a: /* CapsLock */
949 case 0x45: /* NumLock */
950 if (!down)
951 vs->modifiers_state[keycode] ^= 1;
952 break;
955 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
956 /* If the numlock state needs to change then simulate an additional
957 keypress before sending this one. This will happen if the user
958 toggles numlock away from the VNC window.
960 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
961 if (!vs->modifiers_state[0x45]) {
962 vs->modifiers_state[0x45] = 1;
963 press_key(vs, 0xff7f);
965 } else {
966 if (vs->modifiers_state[0x45]) {
967 vs->modifiers_state[0x45] = 0;
968 press_key(vs, 0xff7f);
973 if (is_graphic_console()) {
974 if (keycode & 0x80)
975 kbd_put_keycode(0xe0);
976 if (down)
977 kbd_put_keycode(keycode & 0x7f);
978 else
979 kbd_put_keycode(keycode | 0x80);
980 } else {
981 /* QEMU console emulation */
982 if (down) {
983 switch (keycode) {
984 case 0x2a: /* Left Shift */
985 case 0x36: /* Right Shift */
986 case 0x1d: /* Left CTRL */
987 case 0x9d: /* Right CTRL */
988 case 0x38: /* Left ALT */
989 case 0xb8: /* Right ALT */
990 break;
991 case 0xc8:
992 kbd_put_keysym(QEMU_KEY_UP);
993 break;
994 case 0xd0:
995 kbd_put_keysym(QEMU_KEY_DOWN);
996 break;
997 case 0xcb:
998 kbd_put_keysym(QEMU_KEY_LEFT);
999 break;
1000 case 0xcd:
1001 kbd_put_keysym(QEMU_KEY_RIGHT);
1002 break;
1003 case 0xd3:
1004 kbd_put_keysym(QEMU_KEY_DELETE);
1005 break;
1006 case 0xc7:
1007 kbd_put_keysym(QEMU_KEY_HOME);
1008 break;
1009 case 0xcf:
1010 kbd_put_keysym(QEMU_KEY_END);
1011 break;
1012 case 0xc9:
1013 kbd_put_keysym(QEMU_KEY_PAGEUP);
1014 break;
1015 case 0xd1:
1016 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1017 break;
1018 default:
1019 kbd_put_keysym(sym);
1020 break;
1026 static void key_event(VncState *vs, int down, uint32_t sym)
1028 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1029 sym = sym - 'A' + 'a';
1030 do_key_event(vs, down, sym);
1033 static void framebuffer_update_request(VncState *vs, int incremental,
1034 int x_position, int y_position,
1035 int w, int h)
1037 if (x_position > vs->ds->width)
1038 x_position = vs->ds->width;
1039 if (y_position > vs->ds->height)
1040 y_position = vs->ds->height;
1041 if (x_position + w >= vs->ds->width)
1042 w = vs->ds->width - x_position;
1043 if (y_position + h >= vs->ds->height)
1044 h = vs->ds->height - y_position;
1046 int i;
1047 vs->need_update = 1;
1048 if (!incremental) {
1049 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1051 for (i = 0; i < h; i++) {
1052 vnc_set_bits(vs->dirty_row[y_position + i],
1053 (vs->ds->width / 16), VNC_DIRTY_WORDS);
1054 memset(old_row, 42, vs->ds->width * vs->depth);
1055 old_row += vs->ds->linesize;
1060 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1062 int i;
1064 vs->has_hextile = 0;
1065 vs->has_resize = 0;
1066 vs->has_pointer_type_change = 0;
1067 vs->absolute = -1;
1068 vs->ds->dpy_copy = NULL;
1070 for (i = n_encodings - 1; i >= 0; i--) {
1071 switch (encodings[i]) {
1072 case 0: /* Raw */
1073 vs->has_hextile = 0;
1074 break;
1075 case 1: /* CopyRect */
1076 vs->ds->dpy_copy = vnc_copy;
1077 break;
1078 case 5: /* Hextile */
1079 vs->has_hextile = 1;
1080 break;
1081 case -223: /* DesktopResize */
1082 vs->has_resize = 1;
1083 break;
1084 case -257:
1085 vs->has_pointer_type_change = 1;
1086 break;
1087 default:
1088 break;
1092 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1095 static int compute_nbits(unsigned int val)
1097 int n;
1098 n = 0;
1099 while (val != 0) {
1100 n++;
1101 val >>= 1;
1103 return n;
1106 static void set_pixel_format(VncState *vs,
1107 int bits_per_pixel, int depth,
1108 int big_endian_flag, int true_color_flag,
1109 int red_max, int green_max, int blue_max,
1110 int red_shift, int green_shift, int blue_shift)
1112 int host_big_endian_flag;
1114 #ifdef WORDS_BIGENDIAN
1115 host_big_endian_flag = 1;
1116 #else
1117 host_big_endian_flag = 0;
1118 #endif
1119 if (!true_color_flag) {
1120 fail:
1121 vnc_client_error(vs);
1122 return;
1124 if (bits_per_pixel == 32 &&
1125 host_big_endian_flag == big_endian_flag &&
1126 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1127 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1128 vs->depth = 4;
1129 vs->write_pixels = vnc_write_pixels_copy;
1130 vs->send_hextile_tile = send_hextile_tile_32;
1131 } else
1132 if (bits_per_pixel == 16 &&
1133 host_big_endian_flag == big_endian_flag &&
1134 red_max == 31 && green_max == 63 && blue_max == 31 &&
1135 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1136 vs->depth = 2;
1137 vs->write_pixels = vnc_write_pixels_copy;
1138 vs->send_hextile_tile = send_hextile_tile_16;
1139 } else
1140 if (bits_per_pixel == 8 &&
1141 red_max == 7 && green_max == 7 && blue_max == 3 &&
1142 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1143 vs->depth = 1;
1144 vs->write_pixels = vnc_write_pixels_copy;
1145 vs->send_hextile_tile = send_hextile_tile_8;
1146 } else
1148 /* generic and slower case */
1149 if (bits_per_pixel != 8 &&
1150 bits_per_pixel != 16 &&
1151 bits_per_pixel != 32)
1152 goto fail;
1153 vs->depth = 4;
1154 vs->red_shift = red_shift;
1155 vs->red_max = red_max;
1156 vs->red_shift1 = 24 - compute_nbits(red_max);
1157 vs->green_shift = green_shift;
1158 vs->green_max = green_max;
1159 vs->green_shift1 = 16 - compute_nbits(green_max);
1160 vs->blue_shift = blue_shift;
1161 vs->blue_max = blue_max;
1162 vs->blue_shift1 = 8 - compute_nbits(blue_max);
1163 vs->pix_bpp = bits_per_pixel / 8;
1164 vs->pix_big_endian = big_endian_flag;
1165 vs->write_pixels = vnc_write_pixels_generic;
1166 vs->send_hextile_tile = send_hextile_tile_generic;
1169 vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1170 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1171 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
1173 vga_hw_invalidate();
1174 vga_hw_update();
1177 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1179 int i;
1180 uint16_t limit;
1182 switch (data[0]) {
1183 case 0:
1184 if (len == 1)
1185 return 20;
1187 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1188 read_u8(data, 6), read_u8(data, 7),
1189 read_u16(data, 8), read_u16(data, 10),
1190 read_u16(data, 12), read_u8(data, 14),
1191 read_u8(data, 15), read_u8(data, 16));
1192 break;
1193 case 2:
1194 if (len == 1)
1195 return 4;
1197 if (len == 4)
1198 return 4 + (read_u16(data, 2) * 4);
1200 limit = read_u16(data, 2);
1201 for (i = 0; i < limit; i++) {
1202 int32_t val = read_s32(data, 4 + (i * 4));
1203 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1206 set_encodings(vs, (int32_t *)(data + 4), limit);
1207 break;
1208 case 3:
1209 if (len == 1)
1210 return 10;
1212 framebuffer_update_request(vs,
1213 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1214 read_u16(data, 6), read_u16(data, 8));
1215 break;
1216 case 4:
1217 if (len == 1)
1218 return 8;
1220 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1221 break;
1222 case 5:
1223 if (len == 1)
1224 return 6;
1226 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1227 break;
1228 case 6:
1229 if (len == 1)
1230 return 8;
1232 if (len == 8) {
1233 uint32_t dlen = read_u32(data, 4);
1234 if (dlen > 0)
1235 return 8 + dlen;
1238 client_cut_text(vs, read_u32(data, 4), data + 8);
1239 break;
1240 default:
1241 printf("Msg: %d\n", data[0]);
1242 vnc_client_error(vs);
1243 break;
1246 vnc_read_when(vs, protocol_client_msg, 1);
1247 return 0;
1250 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1252 char pad[3] = { 0, 0, 0 };
1253 char buf[1024];
1254 int size;
1255 char prog[30] = "QEMU";
1257 vs->width = vs->ds->width;
1258 vs->height = vs->ds->height;
1259 vnc_write_u16(vs, vs->ds->width);
1260 vnc_write_u16(vs, vs->ds->height);
1262 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1263 vnc_write_u8(vs, vs->depth * 8); /* depth */
1264 #ifdef WORDS_BIGENDIAN
1265 vnc_write_u8(vs, 1); /* big-endian-flag */
1266 #else
1267 vnc_write_u8(vs, 0); /* big-endian-flag */
1268 #endif
1269 vnc_write_u8(vs, 1); /* true-color-flag */
1270 if (vs->depth == 4) {
1271 vnc_write_u16(vs, 0xFF); /* red-max */
1272 vnc_write_u16(vs, 0xFF); /* green-max */
1273 vnc_write_u16(vs, 0xFF); /* blue-max */
1274 vnc_write_u8(vs, 16); /* red-shift */
1275 vnc_write_u8(vs, 8); /* green-shift */
1276 vnc_write_u8(vs, 0); /* blue-shift */
1277 vs->send_hextile_tile = send_hextile_tile_32;
1278 } else if (vs->depth == 2) {
1279 vnc_write_u16(vs, 31); /* red-max */
1280 vnc_write_u16(vs, 63); /* green-max */
1281 vnc_write_u16(vs, 31); /* blue-max */
1282 vnc_write_u8(vs, 11); /* red-shift */
1283 vnc_write_u8(vs, 5); /* green-shift */
1284 vnc_write_u8(vs, 0); /* blue-shift */
1285 vs->send_hextile_tile = send_hextile_tile_16;
1286 } else if (vs->depth == 1) {
1287 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1288 vnc_write_u16(vs, 7); /* red-max */
1289 vnc_write_u16(vs, 7); /* green-max */
1290 vnc_write_u16(vs, 3); /* blue-max */
1291 vnc_write_u8(vs, 5); /* red-shift */
1292 vnc_write_u8(vs, 2); /* green-shift */
1293 vnc_write_u8(vs, 0); /* blue-shift */
1294 vs->send_hextile_tile = send_hextile_tile_8;
1296 vs->write_pixels = vnc_write_pixels_copy;
1298 vnc_write(vs, pad, 3); /* padding */
1300 decorate_application_name((char *)prog, sizeof prog);
1302 if (qemu_name)
1303 size = snprintf(buf, sizeof(buf), "%s (%s)", prog, qemu_name);
1304 else
1305 size = snprintf(buf, sizeof(buf), "%s", prog);
1307 vnc_write_u32(vs, size);
1308 vnc_write(vs, buf, size);
1309 vnc_flush(vs);
1311 vnc_read_when(vs, protocol_client_msg, 1);
1313 return 0;
1316 static void make_challenge(VncState *vs)
1318 int i;
1320 srand(time(NULL)+getpid()+getpid()*987654+rand());
1322 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1323 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1326 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1328 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1329 int i, j, pwlen;
1330 unsigned char key[8];
1332 if (!vs->password || !vs->password[0]) {
1333 VNC_DEBUG("No password configured on server");
1334 vnc_write_u32(vs, 1); /* Reject auth */
1335 if (vs->minor >= 8) {
1336 static const char err[] = "Authentication failed";
1337 vnc_write_u32(vs, sizeof(err));
1338 vnc_write(vs, err, sizeof(err));
1340 vnc_flush(vs);
1341 vnc_client_error(vs);
1342 return 0;
1345 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1347 /* Calculate the expected challenge response */
1348 pwlen = strlen(vs->password);
1349 for (i=0; i<sizeof(key); i++)
1350 key[i] = i<pwlen ? vs->password[i] : 0;
1351 deskey(key, EN0);
1352 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1353 des(response+j, response+j);
1355 /* Compare expected vs actual challenge response */
1356 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1357 VNC_DEBUG("Client challenge reponse did not match\n");
1358 vnc_write_u32(vs, 1); /* Reject auth */
1359 if (vs->minor >= 8) {
1360 static const char err[] = "Authentication failed";
1361 vnc_write_u32(vs, sizeof(err));
1362 vnc_write(vs, err, sizeof(err));
1364 vnc_flush(vs);
1365 vnc_client_error(vs);
1366 } else {
1367 VNC_DEBUG("Accepting VNC challenge response\n");
1368 vnc_write_u32(vs, 0); /* Accept auth */
1369 vnc_flush(vs);
1371 vnc_read_when(vs, protocol_client_init, 1);
1373 return 0;
1376 static int start_auth_vnc(VncState *vs)
1378 make_challenge(vs);
1379 /* Send client a 'random' challenge */
1380 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1381 vnc_flush(vs);
1383 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1384 return 0;
1388 #if CONFIG_VNC_TLS
1389 #define DH_BITS 1024
1390 static gnutls_dh_params_t dh_params;
1392 static int vnc_tls_initialize(void)
1394 static int tlsinitialized = 0;
1396 if (tlsinitialized)
1397 return 1;
1399 if (gnutls_global_init () < 0)
1400 return 0;
1402 /* XXX ought to re-generate diffie-hellmen params periodically */
1403 if (gnutls_dh_params_init (&dh_params) < 0)
1404 return 0;
1405 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1406 return 0;
1408 #if _VNC_DEBUG == 2
1409 gnutls_global_set_log_level(10);
1410 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1411 #endif
1413 tlsinitialized = 1;
1415 return 1;
1418 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1420 gnutls_anon_server_credentials anon_cred;
1421 int ret;
1423 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1424 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1425 return NULL;
1428 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1430 return anon_cred;
1434 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1436 gnutls_certificate_credentials_t x509_cred;
1437 int ret;
1439 if (!vs->x509cacert) {
1440 VNC_DEBUG("No CA x509 certificate specified\n");
1441 return NULL;
1443 if (!vs->x509cert) {
1444 VNC_DEBUG("No server x509 certificate specified\n");
1445 return NULL;
1447 if (!vs->x509key) {
1448 VNC_DEBUG("No server private key specified\n");
1449 return NULL;
1452 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1453 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1454 return NULL;
1456 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1457 vs->x509cacert,
1458 GNUTLS_X509_FMT_PEM)) < 0) {
1459 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1460 gnutls_certificate_free_credentials(x509_cred);
1461 return NULL;
1464 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1465 vs->x509cert,
1466 vs->x509key,
1467 GNUTLS_X509_FMT_PEM)) < 0) {
1468 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1469 gnutls_certificate_free_credentials(x509_cred);
1470 return NULL;
1473 if (vs->x509cacrl) {
1474 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1475 vs->x509cacrl,
1476 GNUTLS_X509_FMT_PEM)) < 0) {
1477 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1478 gnutls_certificate_free_credentials(x509_cred);
1479 return NULL;
1483 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1485 return x509_cred;
1488 static int vnc_validate_certificate(struct VncState *vs)
1490 int ret;
1491 unsigned int status;
1492 const gnutls_datum_t *certs;
1493 unsigned int nCerts, i;
1494 time_t now;
1496 VNC_DEBUG("Validating client certificate\n");
1497 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1498 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1499 return -1;
1502 if ((now = time(NULL)) == ((time_t)-1)) {
1503 return -1;
1506 if (status != 0) {
1507 if (status & GNUTLS_CERT_INVALID)
1508 VNC_DEBUG("The certificate is not trusted.\n");
1510 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1511 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1513 if (status & GNUTLS_CERT_REVOKED)
1514 VNC_DEBUG("The certificate has been revoked.\n");
1516 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1517 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1519 return -1;
1520 } else {
1521 VNC_DEBUG("Certificate is valid!\n");
1524 /* Only support x509 for now */
1525 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1526 return -1;
1528 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1529 return -1;
1531 for (i = 0 ; i < nCerts ; i++) {
1532 gnutls_x509_crt_t cert;
1533 VNC_DEBUG ("Checking certificate chain %d\n", i);
1534 if (gnutls_x509_crt_init (&cert) < 0)
1535 return -1;
1537 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1538 gnutls_x509_crt_deinit (cert);
1539 return -1;
1542 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1543 VNC_DEBUG("The certificate has expired\n");
1544 gnutls_x509_crt_deinit (cert);
1545 return -1;
1548 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1549 VNC_DEBUG("The certificate is not yet activated\n");
1550 gnutls_x509_crt_deinit (cert);
1551 return -1;
1554 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1555 VNC_DEBUG("The certificate is not yet activated\n");
1556 gnutls_x509_crt_deinit (cert);
1557 return -1;
1560 gnutls_x509_crt_deinit (cert);
1563 return 0;
1567 static int start_auth_vencrypt_subauth(VncState *vs)
1569 switch (vs->subauth) {
1570 case VNC_AUTH_VENCRYPT_TLSNONE:
1571 case VNC_AUTH_VENCRYPT_X509NONE:
1572 VNC_DEBUG("Accept TLS auth none\n");
1573 vnc_write_u32(vs, 0); /* Accept auth completion */
1574 vnc_read_when(vs, protocol_client_init, 1);
1575 break;
1577 case VNC_AUTH_VENCRYPT_TLSVNC:
1578 case VNC_AUTH_VENCRYPT_X509VNC:
1579 VNC_DEBUG("Start TLS auth VNC\n");
1580 return start_auth_vnc(vs);
1582 default: /* Should not be possible, but just in case */
1583 VNC_DEBUG("Reject auth %d\n", vs->auth);
1584 vnc_write_u8(vs, 1);
1585 if (vs->minor >= 8) {
1586 static const char err[] = "Unsupported authentication type";
1587 vnc_write_u32(vs, sizeof(err));
1588 vnc_write(vs, err, sizeof(err));
1590 vnc_client_error(vs);
1593 return 0;
1596 static void vnc_handshake_io(void *opaque);
1598 static int vnc_continue_handshake(struct VncState *vs) {
1599 int ret;
1601 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1602 if (!gnutls_error_is_fatal(ret)) {
1603 VNC_DEBUG("Handshake interrupted (blocking)\n");
1604 if (!gnutls_record_get_direction(vs->tls_session))
1605 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1606 else
1607 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1608 return 0;
1610 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1611 vnc_client_error(vs);
1612 return -1;
1615 if (vs->x509verify) {
1616 if (vnc_validate_certificate(vs) < 0) {
1617 VNC_DEBUG("Client verification failed\n");
1618 vnc_client_error(vs);
1619 return -1;
1620 } else {
1621 VNC_DEBUG("Client verification passed\n");
1625 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1626 vs->wiremode = VNC_WIREMODE_TLS;
1627 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1629 return start_auth_vencrypt_subauth(vs);
1632 static void vnc_handshake_io(void *opaque) {
1633 struct VncState *vs = (struct VncState *)opaque;
1635 VNC_DEBUG("Handshake IO continue\n");
1636 vnc_continue_handshake(vs);
1639 #define NEED_X509_AUTH(vs) \
1640 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1641 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1642 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1645 static int vnc_start_tls(struct VncState *vs) {
1646 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1647 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1648 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1649 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1651 VNC_DEBUG("Do TLS setup\n");
1652 if (vnc_tls_initialize() < 0) {
1653 VNC_DEBUG("Failed to init TLS\n");
1654 vnc_client_error(vs);
1655 return -1;
1657 if (vs->tls_session == NULL) {
1658 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1659 vnc_client_error(vs);
1660 return -1;
1663 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1664 gnutls_deinit(vs->tls_session);
1665 vs->tls_session = NULL;
1666 vnc_client_error(vs);
1667 return -1;
1670 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1671 gnutls_deinit(vs->tls_session);
1672 vs->tls_session = NULL;
1673 vnc_client_error(vs);
1674 return -1;
1677 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1678 gnutls_deinit(vs->tls_session);
1679 vs->tls_session = NULL;
1680 vnc_client_error(vs);
1681 return -1;
1684 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1685 gnutls_deinit(vs->tls_session);
1686 vs->tls_session = NULL;
1687 vnc_client_error(vs);
1688 return -1;
1691 if (NEED_X509_AUTH(vs)) {
1692 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1693 if (!x509_cred) {
1694 gnutls_deinit(vs->tls_session);
1695 vs->tls_session = NULL;
1696 vnc_client_error(vs);
1697 return -1;
1699 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1700 gnutls_deinit(vs->tls_session);
1701 vs->tls_session = NULL;
1702 gnutls_certificate_free_credentials(x509_cred);
1703 vnc_client_error(vs);
1704 return -1;
1706 if (vs->x509verify) {
1707 VNC_DEBUG("Requesting a client certificate\n");
1708 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1711 } else {
1712 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1713 if (!anon_cred) {
1714 gnutls_deinit(vs->tls_session);
1715 vs->tls_session = NULL;
1716 vnc_client_error(vs);
1717 return -1;
1719 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1720 gnutls_deinit(vs->tls_session);
1721 vs->tls_session = NULL;
1722 gnutls_anon_free_server_credentials(anon_cred);
1723 vnc_client_error(vs);
1724 return -1;
1728 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1729 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1730 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1733 VNC_DEBUG("Start TLS handshake process\n");
1734 return vnc_continue_handshake(vs);
1737 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
1739 int auth = read_u32(data, 0);
1741 if (auth != vs->subauth) {
1742 VNC_DEBUG("Rejecting auth %d\n", auth);
1743 vnc_write_u8(vs, 0); /* Reject auth */
1744 vnc_flush(vs);
1745 vnc_client_error(vs);
1746 } else {
1747 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1748 vnc_write_u8(vs, 1); /* Accept auth */
1749 vnc_flush(vs);
1751 if (vnc_start_tls(vs) < 0) {
1752 VNC_DEBUG("Failed to complete TLS\n");
1753 return 0;
1756 if (vs->wiremode == VNC_WIREMODE_TLS) {
1757 VNC_DEBUG("Starting VeNCrypt subauth\n");
1758 return start_auth_vencrypt_subauth(vs);
1759 } else {
1760 VNC_DEBUG("TLS handshake blocked\n");
1761 return 0;
1764 return 0;
1767 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
1769 if (data[0] != 0 ||
1770 data[1] != 2) {
1771 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1772 vnc_write_u8(vs, 1); /* Reject version */
1773 vnc_flush(vs);
1774 vnc_client_error(vs);
1775 } else {
1776 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1777 vnc_write_u8(vs, 0); /* Accept version */
1778 vnc_write_u8(vs, 1); /* Number of sub-auths */
1779 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1780 vnc_flush(vs);
1781 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1783 return 0;
1786 static int start_auth_vencrypt(VncState *vs)
1788 /* Send VeNCrypt version 0.2 */
1789 vnc_write_u8(vs, 0);
1790 vnc_write_u8(vs, 2);
1792 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1793 return 0;
1795 #endif /* CONFIG_VNC_TLS */
1797 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1799 /* We only advertise 1 auth scheme at a time, so client
1800 * must pick the one we sent. Verify this */
1801 if (data[0] != vs->auth) { /* Reject auth */
1802 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1803 vnc_write_u32(vs, 1);
1804 if (vs->minor >= 8) {
1805 static const char err[] = "Authentication failed";
1806 vnc_write_u32(vs, sizeof(err));
1807 vnc_write(vs, err, sizeof(err));
1809 vnc_client_error(vs);
1810 } else { /* Accept requested auth */
1811 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1812 switch (vs->auth) {
1813 case VNC_AUTH_NONE:
1814 VNC_DEBUG("Accept auth none\n");
1815 if (vs->minor >= 8) {
1816 vnc_write_u32(vs, 0); /* Accept auth completion */
1817 vnc_flush(vs);
1819 vnc_read_when(vs, protocol_client_init, 1);
1820 break;
1822 case VNC_AUTH_VNC:
1823 VNC_DEBUG("Start VNC auth\n");
1824 return start_auth_vnc(vs);
1826 #if CONFIG_VNC_TLS
1827 case VNC_AUTH_VENCRYPT:
1828 VNC_DEBUG("Accept VeNCrypt auth\n");;
1829 return start_auth_vencrypt(vs);
1830 #endif /* CONFIG_VNC_TLS */
1832 default: /* Should not be possible, but just in case */
1833 VNC_DEBUG("Reject auth %d\n", vs->auth);
1834 vnc_write_u8(vs, 1);
1835 if (vs->minor >= 8) {
1836 static const char err[] = "Authentication failed";
1837 vnc_write_u32(vs, sizeof(err));
1838 vnc_write(vs, err, sizeof(err));
1840 vnc_client_error(vs);
1843 return 0;
1846 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1848 char local[13];
1850 memcpy(local, version, 12);
1851 local[12] = 0;
1853 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1854 VNC_DEBUG("Malformed protocol version %s\n", local);
1855 vnc_client_error(vs);
1856 return 0;
1858 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1859 if (vs->major != 3 ||
1860 (vs->minor != 3 &&
1861 vs->minor != 4 &&
1862 vs->minor != 5 &&
1863 vs->minor != 7 &&
1864 vs->minor != 8)) {
1865 VNC_DEBUG("Unsupported client version\n");
1866 vnc_write_u32(vs, VNC_AUTH_INVALID);
1867 vnc_flush(vs);
1868 vnc_client_error(vs);
1869 return 0;
1871 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1872 * as equivalent to v3.3 by servers
1874 if (vs->minor == 4 || vs->minor == 5)
1875 vs->minor = 3;
1877 if (vs->minor == 3) {
1878 if (vs->auth == VNC_AUTH_NONE) {
1879 VNC_DEBUG("Tell client auth none\n");
1880 vnc_write_u32(vs, vs->auth);
1881 vnc_flush(vs);
1882 vnc_read_when(vs, protocol_client_init, 1);
1883 } else if (vs->auth == VNC_AUTH_VNC) {
1884 VNC_DEBUG("Tell client VNC auth\n");
1885 vnc_write_u32(vs, vs->auth);
1886 vnc_flush(vs);
1887 start_auth_vnc(vs);
1888 } else {
1889 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1890 vnc_write_u32(vs, VNC_AUTH_INVALID);
1891 vnc_flush(vs);
1892 vnc_client_error(vs);
1894 } else {
1895 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1896 vnc_write_u8(vs, 1); /* num auth */
1897 vnc_write_u8(vs, vs->auth);
1898 vnc_read_when(vs, protocol_client_auth, 1);
1899 vnc_flush(vs);
1902 return 0;
1905 static void vnc_connect(VncState *vs)
1907 VNC_DEBUG("New client on socket %d\n", vs->csock);
1908 socket_set_nonblock(vs->csock);
1909 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1910 vnc_write(vs, "RFB 003.008\n", 12);
1911 vnc_flush(vs);
1912 vnc_read_when(vs, protocol_version, 12);
1913 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1914 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1915 vs->has_resize = 0;
1916 vs->has_hextile = 0;
1917 vs->ds->dpy_copy = NULL;
1918 vnc_update_client(vs);
1921 static void vnc_listen_read(void *opaque)
1923 VncState *vs = opaque;
1924 struct sockaddr_in addr;
1925 socklen_t addrlen = sizeof(addr);
1927 /* Catch-up */
1928 vga_hw_update();
1930 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1931 if (vs->csock != -1) {
1932 vnc_connect(vs);
1936 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1938 void vnc_display_init(DisplayState *ds)
1940 VncState *vs;
1942 vs = qemu_mallocz(sizeof(VncState));
1943 if (!vs)
1944 exit(1);
1946 ds->opaque = vs;
1947 vnc_state = vs;
1948 vs->display = NULL;
1949 vs->password = NULL;
1951 vs->lsock = -1;
1952 vs->csock = -1;
1953 vs->depth = 4;
1954 vs->last_x = -1;
1955 vs->last_y = -1;
1957 vs->ds = ds;
1959 if (!keyboard_layout)
1960 keyboard_layout = "en-us";
1962 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1963 if (!vs->kbd_layout)
1964 exit(1);
1966 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
1968 vs->ds->data = NULL;
1969 vs->ds->dpy_update = vnc_dpy_update;
1970 vs->ds->dpy_resize = vnc_dpy_resize;
1971 vs->ds->dpy_refresh = NULL;
1973 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1975 vnc_dpy_resize(vs->ds, 640, 400);
1978 #if CONFIG_VNC_TLS
1979 static int vnc_set_x509_credential(VncState *vs,
1980 const char *certdir,
1981 const char *filename,
1982 char **cred,
1983 int ignoreMissing)
1985 struct stat sb;
1987 if (*cred) {
1988 qemu_free(*cred);
1989 *cred = NULL;
1992 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
1993 return -1;
1995 strcpy(*cred, certdir);
1996 strcat(*cred, "/");
1997 strcat(*cred, filename);
1999 VNC_DEBUG("Check %s\n", *cred);
2000 if (stat(*cred, &sb) < 0) {
2001 qemu_free(*cred);
2002 *cred = NULL;
2003 if (ignoreMissing && errno == ENOENT)
2004 return 0;
2005 return -1;
2008 return 0;
2011 static int vnc_set_x509_credential_dir(VncState *vs,
2012 const char *certdir)
2014 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2015 goto cleanup;
2016 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2017 goto cleanup;
2018 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2019 goto cleanup;
2020 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2021 goto cleanup;
2023 return 0;
2025 cleanup:
2026 qemu_free(vs->x509cacert);
2027 qemu_free(vs->x509cacrl);
2028 qemu_free(vs->x509cert);
2029 qemu_free(vs->x509key);
2030 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2031 return -1;
2033 #endif /* CONFIG_VNC_TLS */
2035 void vnc_display_close(DisplayState *ds)
2037 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2039 if (vs->display) {
2040 qemu_free(vs->display);
2041 vs->display = NULL;
2043 if (vs->lsock != -1) {
2044 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2045 close(vs->lsock);
2046 vs->lsock = -1;
2048 if (vs->csock != -1) {
2049 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2050 closesocket(vs->csock);
2051 vs->csock = -1;
2052 buffer_reset(&vs->input);
2053 buffer_reset(&vs->output);
2054 vs->need_update = 0;
2055 #if CONFIG_VNC_TLS
2056 if (vs->tls_session) {
2057 gnutls_deinit(vs->tls_session);
2058 vs->tls_session = NULL;
2060 vs->wiremode = VNC_WIREMODE_CLEAR;
2061 #endif /* CONFIG_VNC_TLS */
2063 vs->auth = VNC_AUTH_INVALID;
2064 #if CONFIG_VNC_TLS
2065 vs->subauth = VNC_AUTH_INVALID;
2066 vs->x509verify = 0;
2067 #endif
2070 int vnc_display_password(DisplayState *ds, const char *password)
2072 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2074 if (vs->password) {
2075 qemu_free(vs->password);
2076 vs->password = NULL;
2078 if (password && password[0]) {
2079 if (!(vs->password = qemu_strdup(password)))
2080 return -1;
2083 return 0;
2086 int vnc_display_open(DisplayState *ds, const char *display)
2088 struct sockaddr *addr;
2089 struct sockaddr_in iaddr;
2090 #ifndef _WIN32
2091 struct sockaddr_un uaddr;
2092 #endif
2093 int reuse_addr, ret;
2094 socklen_t addrlen;
2095 const char *p;
2096 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2097 const char *options;
2098 int password = 0;
2099 int reverse = 0;
2100 #if CONFIG_VNC_TLS
2101 int tls = 0, x509 = 0;
2102 #endif
2104 vnc_display_close(ds);
2105 if (strcmp(display, "none") == 0)
2106 return 0;
2108 if (!(vs->display = strdup(display)))
2109 return -1;
2111 options = display;
2112 while ((options = strchr(options, ','))) {
2113 options++;
2114 if (strncmp(options, "password", 8) == 0) {
2115 password = 1; /* Require password auth */
2116 } else if (strncmp(options, "reverse", 7) == 0) {
2117 reverse = 1;
2118 #if CONFIG_VNC_TLS
2119 } else if (strncmp(options, "tls", 3) == 0) {
2120 tls = 1; /* Require TLS */
2121 } else if (strncmp(options, "x509", 4) == 0) {
2122 char *start, *end;
2123 x509 = 1; /* Require x509 certificates */
2124 if (strncmp(options, "x509verify", 10) == 0)
2125 vs->x509verify = 1; /* ...and verify client certs */
2127 /* Now check for 'x509=/some/path' postfix
2128 * and use that to setup x509 certificate/key paths */
2129 start = strchr(options, '=');
2130 end = strchr(options, ',');
2131 if (start && (!end || (start < end))) {
2132 int len = end ? end-(start+1) : strlen(start+1);
2133 char *path = qemu_malloc(len+1);
2134 strncpy(path, start+1, len);
2135 path[len] = '\0';
2136 VNC_DEBUG("Trying certificate path '%s'\n", path);
2137 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2138 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2139 qemu_free(path);
2140 qemu_free(vs->display);
2141 vs->display = NULL;
2142 return -1;
2144 qemu_free(path);
2145 } else {
2146 fprintf(stderr, "No certificate path provided\n");
2147 qemu_free(vs->display);
2148 vs->display = NULL;
2149 return -1;
2151 #endif
2155 if (password) {
2156 #if CONFIG_VNC_TLS
2157 if (tls) {
2158 vs->auth = VNC_AUTH_VENCRYPT;
2159 if (x509) {
2160 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2161 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2162 } else {
2163 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2164 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2166 } else {
2167 #endif
2168 VNC_DEBUG("Initializing VNC server with password auth\n");
2169 vs->auth = VNC_AUTH_VNC;
2170 #if CONFIG_VNC_TLS
2171 vs->subauth = VNC_AUTH_INVALID;
2173 #endif
2174 } else {
2175 #if CONFIG_VNC_TLS
2176 if (tls) {
2177 vs->auth = VNC_AUTH_VENCRYPT;
2178 if (x509) {
2179 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2180 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2181 } else {
2182 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2183 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2185 } else {
2186 #endif
2187 VNC_DEBUG("Initializing VNC server with no auth\n");
2188 vs->auth = VNC_AUTH_NONE;
2189 #if CONFIG_VNC_TLS
2190 vs->subauth = VNC_AUTH_INVALID;
2192 #endif
2194 #ifndef _WIN32
2195 if (strstart(display, "unix:", &p)) {
2196 addr = (struct sockaddr *)&uaddr;
2197 addrlen = sizeof(uaddr);
2199 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2200 if (vs->lsock == -1) {
2201 fprintf(stderr, "Could not create socket\n");
2202 free(vs->display);
2203 vs->display = NULL;
2204 return -1;
2207 uaddr.sun_family = AF_UNIX;
2208 memset(uaddr.sun_path, 0, 108);
2209 snprintf(uaddr.sun_path, 108, "%s", p);
2211 if (!reverse) {
2212 unlink(uaddr.sun_path);
2214 } else
2215 #endif
2217 addr = (struct sockaddr *)&iaddr;
2218 addrlen = sizeof(iaddr);
2220 if (parse_host_port(&iaddr, display) < 0) {
2221 fprintf(stderr, "Could not parse VNC address\n");
2222 free(vs->display);
2223 vs->display = NULL;
2224 return -1;
2227 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900));
2229 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2230 if (vs->lsock == -1) {
2231 fprintf(stderr, "Could not create socket\n");
2232 free(vs->display);
2233 vs->display = NULL;
2234 return -1;
2237 reuse_addr = 1;
2238 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2239 (const char *)&reuse_addr, sizeof(reuse_addr));
2240 if (ret == -1) {
2241 fprintf(stderr, "setsockopt() failed\n");
2242 close(vs->lsock);
2243 vs->lsock = -1;
2244 free(vs->display);
2245 vs->display = NULL;
2246 return -1;
2250 if (reverse) {
2251 if (connect(vs->lsock, addr, addrlen) == -1) {
2252 fprintf(stderr, "Connection to VNC client failed\n");
2253 close(vs->lsock);
2254 vs->lsock = -1;
2255 free(vs->display);
2256 vs->display = NULL;
2257 return -1;
2258 } else {
2259 vs->csock = vs->lsock;
2260 vs->lsock = -1;
2261 vnc_connect(vs);
2262 return 0;
2266 if (bind(vs->lsock, addr, addrlen) == -1) {
2267 fprintf(stderr, "bind() failed\n");
2268 close(vs->lsock);
2269 vs->lsock = -1;
2270 free(vs->display);
2271 vs->display = NULL;
2272 return -1;
2275 if (listen(vs->lsock, 1) == -1) {
2276 fprintf(stderr, "listen() failed\n");
2277 close(vs->lsock);
2278 vs->lsock = -1;
2279 free(vs->display);
2280 vs->display = NULL;
2281 return -1;
2284 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);