Add serial loopback mode (patch from Hervé Poussineau).
[qemu/mini2440.git] / vnc.c
blobe7f3255c886b5cd6d98c98c9c4eaa3834cc461af
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,
883 y * 0x7FFF / vs->ds->height,
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 0x45: /* NumLock */
949 if (!down)
950 vs->modifiers_state[keycode] ^= 1;
951 break;
954 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
955 /* If the numlock state needs to change then simulate an additional
956 keypress before sending this one. This will happen if the user
957 toggles numlock away from the VNC window.
959 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
960 if (!vs->modifiers_state[0x45]) {
961 vs->modifiers_state[0x45] = 1;
962 press_key(vs, 0xff7f);
964 } else {
965 if (vs->modifiers_state[0x45]) {
966 vs->modifiers_state[0x45] = 0;
967 press_key(vs, 0xff7f);
972 if (is_graphic_console()) {
973 if (keycode & 0x80)
974 kbd_put_keycode(0xe0);
975 if (down)
976 kbd_put_keycode(keycode & 0x7f);
977 else
978 kbd_put_keycode(keycode | 0x80);
979 } else {
980 /* QEMU console emulation */
981 if (down) {
982 switch (keycode) {
983 case 0x2a: /* Left Shift */
984 case 0x36: /* Right Shift */
985 case 0x1d: /* Left CTRL */
986 case 0x9d: /* Right CTRL */
987 case 0x38: /* Left ALT */
988 case 0xb8: /* Right ALT */
989 break;
990 case 0xc8:
991 kbd_put_keysym(QEMU_KEY_UP);
992 break;
993 case 0xd0:
994 kbd_put_keysym(QEMU_KEY_DOWN);
995 break;
996 case 0xcb:
997 kbd_put_keysym(QEMU_KEY_LEFT);
998 break;
999 case 0xcd:
1000 kbd_put_keysym(QEMU_KEY_RIGHT);
1001 break;
1002 case 0xd3:
1003 kbd_put_keysym(QEMU_KEY_DELETE);
1004 break;
1005 case 0xc7:
1006 kbd_put_keysym(QEMU_KEY_HOME);
1007 break;
1008 case 0xcf:
1009 kbd_put_keysym(QEMU_KEY_END);
1010 break;
1011 case 0xc9:
1012 kbd_put_keysym(QEMU_KEY_PAGEUP);
1013 break;
1014 case 0xd1:
1015 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1016 break;
1017 default:
1018 kbd_put_keysym(sym);
1019 break;
1025 static void key_event(VncState *vs, int down, uint32_t sym)
1027 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1028 sym = sym - 'A' + 'a';
1029 do_key_event(vs, down, sym);
1032 static void framebuffer_update_request(VncState *vs, int incremental,
1033 int x_position, int y_position,
1034 int w, int h)
1036 if (x_position > vs->ds->width)
1037 x_position = vs->ds->width;
1038 if (y_position > vs->ds->height)
1039 y_position = vs->ds->height;
1040 if (x_position + w >= vs->ds->width)
1041 w = vs->ds->width - x_position;
1042 if (y_position + h >= vs->ds->height)
1043 h = vs->ds->height - y_position;
1045 int i;
1046 vs->need_update = 1;
1047 if (!incremental) {
1048 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1050 for (i = 0; i < h; i++) {
1051 vnc_set_bits(vs->dirty_row[y_position + i],
1052 (vs->ds->width / 16), VNC_DIRTY_WORDS);
1053 memset(old_row, 42, vs->ds->width * vs->depth);
1054 old_row += vs->ds->linesize;
1059 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1061 int i;
1063 vs->has_hextile = 0;
1064 vs->has_resize = 0;
1065 vs->has_pointer_type_change = 0;
1066 vs->absolute = -1;
1067 vs->ds->dpy_copy = NULL;
1069 for (i = n_encodings - 1; i >= 0; i--) {
1070 switch (encodings[i]) {
1071 case 0: /* Raw */
1072 vs->has_hextile = 0;
1073 break;
1074 case 1: /* CopyRect */
1075 vs->ds->dpy_copy = vnc_copy;
1076 break;
1077 case 5: /* Hextile */
1078 vs->has_hextile = 1;
1079 break;
1080 case -223: /* DesktopResize */
1081 vs->has_resize = 1;
1082 break;
1083 case -257:
1084 vs->has_pointer_type_change = 1;
1085 break;
1086 default:
1087 break;
1091 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1094 static int compute_nbits(unsigned int val)
1096 int n;
1097 n = 0;
1098 while (val != 0) {
1099 n++;
1100 val >>= 1;
1102 return n;
1105 static void set_pixel_format(VncState *vs,
1106 int bits_per_pixel, int depth,
1107 int big_endian_flag, int true_color_flag,
1108 int red_max, int green_max, int blue_max,
1109 int red_shift, int green_shift, int blue_shift)
1111 int host_big_endian_flag;
1113 #ifdef WORDS_BIGENDIAN
1114 host_big_endian_flag = 1;
1115 #else
1116 host_big_endian_flag = 0;
1117 #endif
1118 if (!true_color_flag) {
1119 fail:
1120 vnc_client_error(vs);
1121 return;
1123 if (bits_per_pixel == 32 &&
1124 host_big_endian_flag == big_endian_flag &&
1125 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1126 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1127 vs->depth = 4;
1128 vs->write_pixels = vnc_write_pixels_copy;
1129 vs->send_hextile_tile = send_hextile_tile_32;
1130 } else
1131 if (bits_per_pixel == 16 &&
1132 host_big_endian_flag == big_endian_flag &&
1133 red_max == 31 && green_max == 63 && blue_max == 31 &&
1134 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1135 vs->depth = 2;
1136 vs->write_pixels = vnc_write_pixels_copy;
1137 vs->send_hextile_tile = send_hextile_tile_16;
1138 } else
1139 if (bits_per_pixel == 8 &&
1140 red_max == 7 && green_max == 7 && blue_max == 3 &&
1141 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1142 vs->depth = 1;
1143 vs->write_pixels = vnc_write_pixels_copy;
1144 vs->send_hextile_tile = send_hextile_tile_8;
1145 } else
1147 /* generic and slower case */
1148 if (bits_per_pixel != 8 &&
1149 bits_per_pixel != 16 &&
1150 bits_per_pixel != 32)
1151 goto fail;
1152 vs->depth = 4;
1153 vs->red_shift = red_shift;
1154 vs->red_max = red_max;
1155 vs->red_shift1 = 24 - compute_nbits(red_max);
1156 vs->green_shift = green_shift;
1157 vs->green_max = green_max;
1158 vs->green_shift1 = 16 - compute_nbits(green_max);
1159 vs->blue_shift = blue_shift;
1160 vs->blue_max = blue_max;
1161 vs->blue_shift1 = 8 - compute_nbits(blue_max);
1162 vs->pix_bpp = bits_per_pixel / 8;
1163 vs->pix_big_endian = big_endian_flag;
1164 vs->write_pixels = vnc_write_pixels_generic;
1165 vs->send_hextile_tile = send_hextile_tile_generic;
1168 vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1169 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1170 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
1172 vga_hw_invalidate();
1173 vga_hw_update();
1176 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1178 int i;
1179 uint16_t limit;
1181 switch (data[0]) {
1182 case 0:
1183 if (len == 1)
1184 return 20;
1186 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1187 read_u8(data, 6), read_u8(data, 7),
1188 read_u16(data, 8), read_u16(data, 10),
1189 read_u16(data, 12), read_u8(data, 14),
1190 read_u8(data, 15), read_u8(data, 16));
1191 break;
1192 case 2:
1193 if (len == 1)
1194 return 4;
1196 if (len == 4)
1197 return 4 + (read_u16(data, 2) * 4);
1199 limit = read_u16(data, 2);
1200 for (i = 0; i < limit; i++) {
1201 int32_t val = read_s32(data, 4 + (i * 4));
1202 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1205 set_encodings(vs, (int32_t *)(data + 4), limit);
1206 break;
1207 case 3:
1208 if (len == 1)
1209 return 10;
1211 framebuffer_update_request(vs,
1212 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1213 read_u16(data, 6), read_u16(data, 8));
1214 break;
1215 case 4:
1216 if (len == 1)
1217 return 8;
1219 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1220 break;
1221 case 5:
1222 if (len == 1)
1223 return 6;
1225 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1226 break;
1227 case 6:
1228 if (len == 1)
1229 return 8;
1231 if (len == 8) {
1232 uint32_t dlen = read_u32(data, 4);
1233 if (dlen > 0)
1234 return 8 + dlen;
1237 client_cut_text(vs, read_u32(data, 4), data + 8);
1238 break;
1239 default:
1240 printf("Msg: %d\n", data[0]);
1241 vnc_client_error(vs);
1242 break;
1245 vnc_read_when(vs, protocol_client_msg, 1);
1246 return 0;
1249 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1251 char pad[3] = { 0, 0, 0 };
1252 char buf[1024];
1253 int size;
1255 vs->width = vs->ds->width;
1256 vs->height = vs->ds->height;
1257 vnc_write_u16(vs, vs->ds->width);
1258 vnc_write_u16(vs, vs->ds->height);
1260 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1261 vnc_write_u8(vs, vs->depth * 8); /* depth */
1262 #ifdef WORDS_BIGENDIAN
1263 vnc_write_u8(vs, 1); /* big-endian-flag */
1264 #else
1265 vnc_write_u8(vs, 0); /* big-endian-flag */
1266 #endif
1267 vnc_write_u8(vs, 1); /* true-color-flag */
1268 if (vs->depth == 4) {
1269 vnc_write_u16(vs, 0xFF); /* red-max */
1270 vnc_write_u16(vs, 0xFF); /* green-max */
1271 vnc_write_u16(vs, 0xFF); /* blue-max */
1272 vnc_write_u8(vs, 16); /* red-shift */
1273 vnc_write_u8(vs, 8); /* green-shift */
1274 vnc_write_u8(vs, 0); /* blue-shift */
1275 vs->send_hextile_tile = send_hextile_tile_32;
1276 } else if (vs->depth == 2) {
1277 vnc_write_u16(vs, 31); /* red-max */
1278 vnc_write_u16(vs, 63); /* green-max */
1279 vnc_write_u16(vs, 31); /* blue-max */
1280 vnc_write_u8(vs, 11); /* red-shift */
1281 vnc_write_u8(vs, 5); /* green-shift */
1282 vnc_write_u8(vs, 0); /* blue-shift */
1283 vs->send_hextile_tile = send_hextile_tile_16;
1284 } else if (vs->depth == 1) {
1285 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1286 vnc_write_u16(vs, 7); /* red-max */
1287 vnc_write_u16(vs, 7); /* green-max */
1288 vnc_write_u16(vs, 3); /* blue-max */
1289 vnc_write_u8(vs, 5); /* red-shift */
1290 vnc_write_u8(vs, 2); /* green-shift */
1291 vnc_write_u8(vs, 0); /* blue-shift */
1292 vs->send_hextile_tile = send_hextile_tile_8;
1294 vs->write_pixels = vnc_write_pixels_copy;
1296 vnc_write(vs, pad, 3); /* padding */
1298 if (qemu_name)
1299 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1300 else
1301 size = snprintf(buf, sizeof(buf), "QEMU");
1303 vnc_write_u32(vs, size);
1304 vnc_write(vs, buf, size);
1305 vnc_flush(vs);
1307 vnc_read_when(vs, protocol_client_msg, 1);
1309 return 0;
1312 static void make_challenge(VncState *vs)
1314 int i;
1316 srand(time(NULL)+getpid()+getpid()*987654+rand());
1318 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1319 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1322 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1324 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1325 int i, j, pwlen;
1326 unsigned char key[8];
1328 if (!vs->password || !vs->password[0]) {
1329 VNC_DEBUG("No password configured on server");
1330 vnc_write_u32(vs, 1); /* Reject auth */
1331 if (vs->minor >= 8) {
1332 static const char err[] = "Authentication failed";
1333 vnc_write_u32(vs, sizeof(err));
1334 vnc_write(vs, err, sizeof(err));
1336 vnc_flush(vs);
1337 vnc_client_error(vs);
1338 return 0;
1341 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1343 /* Calculate the expected challenge response */
1344 pwlen = strlen(vs->password);
1345 for (i=0; i<sizeof(key); i++)
1346 key[i] = i<pwlen ? vs->password[i] : 0;
1347 deskey(key, EN0);
1348 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1349 des(response+j, response+j);
1351 /* Compare expected vs actual challenge response */
1352 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1353 VNC_DEBUG("Client challenge reponse did not match\n");
1354 vnc_write_u32(vs, 1); /* Reject auth */
1355 if (vs->minor >= 8) {
1356 static const char err[] = "Authentication failed";
1357 vnc_write_u32(vs, sizeof(err));
1358 vnc_write(vs, err, sizeof(err));
1360 vnc_flush(vs);
1361 vnc_client_error(vs);
1362 } else {
1363 VNC_DEBUG("Accepting VNC challenge response\n");
1364 vnc_write_u32(vs, 0); /* Accept auth */
1365 vnc_flush(vs);
1367 vnc_read_when(vs, protocol_client_init, 1);
1369 return 0;
1372 static int start_auth_vnc(VncState *vs)
1374 make_challenge(vs);
1375 /* Send client a 'random' challenge */
1376 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1377 vnc_flush(vs);
1379 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1380 return 0;
1384 #if CONFIG_VNC_TLS
1385 #define DH_BITS 1024
1386 static gnutls_dh_params_t dh_params;
1388 static int vnc_tls_initialize(void)
1390 static int tlsinitialized = 0;
1392 if (tlsinitialized)
1393 return 1;
1395 if (gnutls_global_init () < 0)
1396 return 0;
1398 /* XXX ought to re-generate diffie-hellmen params periodically */
1399 if (gnutls_dh_params_init (&dh_params) < 0)
1400 return 0;
1401 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1402 return 0;
1404 #if _VNC_DEBUG == 2
1405 gnutls_global_set_log_level(10);
1406 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1407 #endif
1409 tlsinitialized = 1;
1411 return 1;
1414 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1416 gnutls_anon_server_credentials anon_cred;
1417 int ret;
1419 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1420 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1421 return NULL;
1424 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1426 return anon_cred;
1430 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1432 gnutls_certificate_credentials_t x509_cred;
1433 int ret;
1435 if (!vs->x509cacert) {
1436 VNC_DEBUG("No CA x509 certificate specified\n");
1437 return NULL;
1439 if (!vs->x509cert) {
1440 VNC_DEBUG("No server x509 certificate specified\n");
1441 return NULL;
1443 if (!vs->x509key) {
1444 VNC_DEBUG("No server private key specified\n");
1445 return NULL;
1448 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1449 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1450 return NULL;
1452 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1453 vs->x509cacert,
1454 GNUTLS_X509_FMT_PEM)) < 0) {
1455 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1456 gnutls_certificate_free_credentials(x509_cred);
1457 return NULL;
1460 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1461 vs->x509cert,
1462 vs->x509key,
1463 GNUTLS_X509_FMT_PEM)) < 0) {
1464 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1465 gnutls_certificate_free_credentials(x509_cred);
1466 return NULL;
1469 if (vs->x509cacrl) {
1470 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1471 vs->x509cacrl,
1472 GNUTLS_X509_FMT_PEM)) < 0) {
1473 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1474 gnutls_certificate_free_credentials(x509_cred);
1475 return NULL;
1479 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1481 return x509_cred;
1484 static int vnc_validate_certificate(struct VncState *vs)
1486 int ret;
1487 unsigned int status;
1488 const gnutls_datum_t *certs;
1489 unsigned int nCerts, i;
1490 time_t now;
1492 VNC_DEBUG("Validating client certificate\n");
1493 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1494 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1495 return -1;
1498 if ((now = time(NULL)) == ((time_t)-1)) {
1499 return -1;
1502 if (status != 0) {
1503 if (status & GNUTLS_CERT_INVALID)
1504 VNC_DEBUG("The certificate is not trusted.\n");
1506 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1507 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1509 if (status & GNUTLS_CERT_REVOKED)
1510 VNC_DEBUG("The certificate has been revoked.\n");
1512 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1513 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1515 return -1;
1516 } else {
1517 VNC_DEBUG("Certificate is valid!\n");
1520 /* Only support x509 for now */
1521 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1522 return -1;
1524 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1525 return -1;
1527 for (i = 0 ; i < nCerts ; i++) {
1528 gnutls_x509_crt_t cert;
1529 VNC_DEBUG ("Checking certificate chain %d\n", i);
1530 if (gnutls_x509_crt_init (&cert) < 0)
1531 return -1;
1533 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1534 gnutls_x509_crt_deinit (cert);
1535 return -1;
1538 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1539 VNC_DEBUG("The certificate has expired\n");
1540 gnutls_x509_crt_deinit (cert);
1541 return -1;
1544 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1545 VNC_DEBUG("The certificate is not yet activated\n");
1546 gnutls_x509_crt_deinit (cert);
1547 return -1;
1550 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1551 VNC_DEBUG("The certificate is not yet activated\n");
1552 gnutls_x509_crt_deinit (cert);
1553 return -1;
1556 gnutls_x509_crt_deinit (cert);
1559 return 0;
1563 static int start_auth_vencrypt_subauth(VncState *vs)
1565 switch (vs->subauth) {
1566 case VNC_AUTH_VENCRYPT_TLSNONE:
1567 case VNC_AUTH_VENCRYPT_X509NONE:
1568 VNC_DEBUG("Accept TLS auth none\n");
1569 vnc_write_u32(vs, 0); /* Accept auth completion */
1570 vnc_read_when(vs, protocol_client_init, 1);
1571 break;
1573 case VNC_AUTH_VENCRYPT_TLSVNC:
1574 case VNC_AUTH_VENCRYPT_X509VNC:
1575 VNC_DEBUG("Start TLS auth VNC\n");
1576 return start_auth_vnc(vs);
1578 default: /* Should not be possible, but just in case */
1579 VNC_DEBUG("Reject auth %d\n", vs->auth);
1580 vnc_write_u8(vs, 1);
1581 if (vs->minor >= 8) {
1582 static const char err[] = "Unsupported authentication type";
1583 vnc_write_u32(vs, sizeof(err));
1584 vnc_write(vs, err, sizeof(err));
1586 vnc_client_error(vs);
1589 return 0;
1592 static void vnc_handshake_io(void *opaque);
1594 static int vnc_continue_handshake(struct VncState *vs) {
1595 int ret;
1597 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1598 if (!gnutls_error_is_fatal(ret)) {
1599 VNC_DEBUG("Handshake interrupted (blocking)\n");
1600 if (!gnutls_record_get_direction(vs->tls_session))
1601 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1602 else
1603 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1604 return 0;
1606 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1607 vnc_client_error(vs);
1608 return -1;
1611 if (vs->x509verify) {
1612 if (vnc_validate_certificate(vs) < 0) {
1613 VNC_DEBUG("Client verification failed\n");
1614 vnc_client_error(vs);
1615 return -1;
1616 } else {
1617 VNC_DEBUG("Client verification passed\n");
1621 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1622 vs->wiremode = VNC_WIREMODE_TLS;
1623 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1625 return start_auth_vencrypt_subauth(vs);
1628 static void vnc_handshake_io(void *opaque) {
1629 struct VncState *vs = (struct VncState *)opaque;
1631 VNC_DEBUG("Handshake IO continue\n");
1632 vnc_continue_handshake(vs);
1635 #define NEED_X509_AUTH(vs) \
1636 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1637 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1638 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1641 static int vnc_start_tls(struct VncState *vs) {
1642 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1643 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1644 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1645 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1647 VNC_DEBUG("Do TLS setup\n");
1648 if (vnc_tls_initialize() < 0) {
1649 VNC_DEBUG("Failed to init TLS\n");
1650 vnc_client_error(vs);
1651 return -1;
1653 if (vs->tls_session == NULL) {
1654 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1655 vnc_client_error(vs);
1656 return -1;
1659 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1660 gnutls_deinit(vs->tls_session);
1661 vs->tls_session = NULL;
1662 vnc_client_error(vs);
1663 return -1;
1666 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1667 gnutls_deinit(vs->tls_session);
1668 vs->tls_session = NULL;
1669 vnc_client_error(vs);
1670 return -1;
1673 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1674 gnutls_deinit(vs->tls_session);
1675 vs->tls_session = NULL;
1676 vnc_client_error(vs);
1677 return -1;
1680 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1681 gnutls_deinit(vs->tls_session);
1682 vs->tls_session = NULL;
1683 vnc_client_error(vs);
1684 return -1;
1687 if (NEED_X509_AUTH(vs)) {
1688 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1689 if (!x509_cred) {
1690 gnutls_deinit(vs->tls_session);
1691 vs->tls_session = NULL;
1692 vnc_client_error(vs);
1693 return -1;
1695 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1696 gnutls_deinit(vs->tls_session);
1697 vs->tls_session = NULL;
1698 gnutls_certificate_free_credentials(x509_cred);
1699 vnc_client_error(vs);
1700 return -1;
1702 if (vs->x509verify) {
1703 VNC_DEBUG("Requesting a client certificate\n");
1704 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1707 } else {
1708 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1709 if (!anon_cred) {
1710 gnutls_deinit(vs->tls_session);
1711 vs->tls_session = NULL;
1712 vnc_client_error(vs);
1713 return -1;
1715 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1716 gnutls_deinit(vs->tls_session);
1717 vs->tls_session = NULL;
1718 gnutls_anon_free_server_credentials(anon_cred);
1719 vnc_client_error(vs);
1720 return -1;
1724 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1725 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1726 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1729 VNC_DEBUG("Start TLS handshake process\n");
1730 return vnc_continue_handshake(vs);
1733 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
1735 int auth = read_u32(data, 0);
1737 if (auth != vs->subauth) {
1738 VNC_DEBUG("Rejecting auth %d\n", auth);
1739 vnc_write_u8(vs, 0); /* Reject auth */
1740 vnc_flush(vs);
1741 vnc_client_error(vs);
1742 } else {
1743 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1744 vnc_write_u8(vs, 1); /* Accept auth */
1745 vnc_flush(vs);
1747 if (vnc_start_tls(vs) < 0) {
1748 VNC_DEBUG("Failed to complete TLS\n");
1749 return 0;
1752 if (vs->wiremode == VNC_WIREMODE_TLS) {
1753 VNC_DEBUG("Starting VeNCrypt subauth\n");
1754 return start_auth_vencrypt_subauth(vs);
1755 } else {
1756 VNC_DEBUG("TLS handshake blocked\n");
1757 return 0;
1760 return 0;
1763 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
1765 if (data[0] != 0 ||
1766 data[1] != 2) {
1767 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1768 vnc_write_u8(vs, 1); /* Reject version */
1769 vnc_flush(vs);
1770 vnc_client_error(vs);
1771 } else {
1772 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1773 vnc_write_u8(vs, 0); /* Accept version */
1774 vnc_write_u8(vs, 1); /* Number of sub-auths */
1775 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1776 vnc_flush(vs);
1777 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1779 return 0;
1782 static int start_auth_vencrypt(VncState *vs)
1784 /* Send VeNCrypt version 0.2 */
1785 vnc_write_u8(vs, 0);
1786 vnc_write_u8(vs, 2);
1788 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1789 return 0;
1791 #endif /* CONFIG_VNC_TLS */
1793 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1795 /* We only advertise 1 auth scheme at a time, so client
1796 * must pick the one we sent. Verify this */
1797 if (data[0] != vs->auth) { /* Reject auth */
1798 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1799 vnc_write_u32(vs, 1);
1800 if (vs->minor >= 8) {
1801 static const char err[] = "Authentication failed";
1802 vnc_write_u32(vs, sizeof(err));
1803 vnc_write(vs, err, sizeof(err));
1805 vnc_client_error(vs);
1806 } else { /* Accept requested auth */
1807 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1808 switch (vs->auth) {
1809 case VNC_AUTH_NONE:
1810 VNC_DEBUG("Accept auth none\n");
1811 if (vs->minor >= 8) {
1812 vnc_write_u32(vs, 0); /* Accept auth completion */
1813 vnc_flush(vs);
1815 vnc_read_when(vs, protocol_client_init, 1);
1816 break;
1818 case VNC_AUTH_VNC:
1819 VNC_DEBUG("Start VNC auth\n");
1820 return start_auth_vnc(vs);
1822 #if CONFIG_VNC_TLS
1823 case VNC_AUTH_VENCRYPT:
1824 VNC_DEBUG("Accept VeNCrypt auth\n");;
1825 return start_auth_vencrypt(vs);
1826 #endif /* CONFIG_VNC_TLS */
1828 default: /* Should not be possible, but just in case */
1829 VNC_DEBUG("Reject auth %d\n", vs->auth);
1830 vnc_write_u8(vs, 1);
1831 if (vs->minor >= 8) {
1832 static const char err[] = "Authentication failed";
1833 vnc_write_u32(vs, sizeof(err));
1834 vnc_write(vs, err, sizeof(err));
1836 vnc_client_error(vs);
1839 return 0;
1842 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1844 char local[13];
1846 memcpy(local, version, 12);
1847 local[12] = 0;
1849 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1850 VNC_DEBUG("Malformed protocol version %s\n", local);
1851 vnc_client_error(vs);
1852 return 0;
1854 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1855 if (vs->major != 3 ||
1856 (vs->minor != 3 &&
1857 vs->minor != 4 &&
1858 vs->minor != 5 &&
1859 vs->minor != 7 &&
1860 vs->minor != 8)) {
1861 VNC_DEBUG("Unsupported client version\n");
1862 vnc_write_u32(vs, VNC_AUTH_INVALID);
1863 vnc_flush(vs);
1864 vnc_client_error(vs);
1865 return 0;
1867 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1868 * as equivalent to v3.3 by servers
1870 if (vs->minor == 4 || vs->minor == 5)
1871 vs->minor = 3;
1873 if (vs->minor == 3) {
1874 if (vs->auth == VNC_AUTH_NONE) {
1875 VNC_DEBUG("Tell client auth none\n");
1876 vnc_write_u32(vs, vs->auth);
1877 vnc_flush(vs);
1878 vnc_read_when(vs, protocol_client_init, 1);
1879 } else if (vs->auth == VNC_AUTH_VNC) {
1880 VNC_DEBUG("Tell client VNC auth\n");
1881 vnc_write_u32(vs, vs->auth);
1882 vnc_flush(vs);
1883 start_auth_vnc(vs);
1884 } else {
1885 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1886 vnc_write_u32(vs, VNC_AUTH_INVALID);
1887 vnc_flush(vs);
1888 vnc_client_error(vs);
1890 } else {
1891 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1892 vnc_write_u8(vs, 1); /* num auth */
1893 vnc_write_u8(vs, vs->auth);
1894 vnc_read_when(vs, protocol_client_auth, 1);
1895 vnc_flush(vs);
1898 return 0;
1901 static void vnc_connect(VncState *vs)
1903 VNC_DEBUG("New client on socket %d\n", vs->csock);
1904 socket_set_nonblock(vs->csock);
1905 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1906 vnc_write(vs, "RFB 003.008\n", 12);
1907 vnc_flush(vs);
1908 vnc_read_when(vs, protocol_version, 12);
1909 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1910 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1911 vs->has_resize = 0;
1912 vs->has_hextile = 0;
1913 vs->ds->dpy_copy = NULL;
1914 vnc_update_client(vs);
1917 static void vnc_listen_read(void *opaque)
1919 VncState *vs = opaque;
1920 struct sockaddr_in addr;
1921 socklen_t addrlen = sizeof(addr);
1923 /* Catch-up */
1924 vga_hw_update();
1926 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1927 if (vs->csock != -1) {
1928 vnc_connect(vs);
1932 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1934 void vnc_display_init(DisplayState *ds)
1936 VncState *vs;
1938 vs = qemu_mallocz(sizeof(VncState));
1939 if (!vs)
1940 exit(1);
1942 ds->opaque = vs;
1943 vnc_state = vs;
1944 vs->display = NULL;
1945 vs->password = NULL;
1947 vs->lsock = -1;
1948 vs->csock = -1;
1949 vs->depth = 4;
1950 vs->last_x = -1;
1951 vs->last_y = -1;
1953 vs->ds = ds;
1955 if (!keyboard_layout)
1956 keyboard_layout = "en-us";
1958 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1959 if (!vs->kbd_layout)
1960 exit(1);
1962 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
1964 vs->ds->data = NULL;
1965 vs->ds->dpy_update = vnc_dpy_update;
1966 vs->ds->dpy_resize = vnc_dpy_resize;
1967 vs->ds->dpy_refresh = NULL;
1969 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1971 vnc_dpy_resize(vs->ds, 640, 400);
1974 #if CONFIG_VNC_TLS
1975 static int vnc_set_x509_credential(VncState *vs,
1976 const char *certdir,
1977 const char *filename,
1978 char **cred,
1979 int ignoreMissing)
1981 struct stat sb;
1983 if (*cred) {
1984 qemu_free(*cred);
1985 *cred = NULL;
1988 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
1989 return -1;
1991 strcpy(*cred, certdir);
1992 strcat(*cred, "/");
1993 strcat(*cred, filename);
1995 VNC_DEBUG("Check %s\n", *cred);
1996 if (stat(*cred, &sb) < 0) {
1997 qemu_free(*cred);
1998 *cred = NULL;
1999 if (ignoreMissing && errno == ENOENT)
2000 return 0;
2001 return -1;
2004 return 0;
2007 static int vnc_set_x509_credential_dir(VncState *vs,
2008 const char *certdir)
2010 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2011 goto cleanup;
2012 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2013 goto cleanup;
2014 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2015 goto cleanup;
2016 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2017 goto cleanup;
2019 return 0;
2021 cleanup:
2022 qemu_free(vs->x509cacert);
2023 qemu_free(vs->x509cacrl);
2024 qemu_free(vs->x509cert);
2025 qemu_free(vs->x509key);
2026 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2027 return -1;
2029 #endif /* CONFIG_VNC_TLS */
2031 void vnc_display_close(DisplayState *ds)
2033 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2035 if (vs->display) {
2036 qemu_free(vs->display);
2037 vs->display = NULL;
2039 if (vs->lsock != -1) {
2040 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2041 close(vs->lsock);
2042 vs->lsock = -1;
2044 if (vs->csock != -1) {
2045 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2046 closesocket(vs->csock);
2047 vs->csock = -1;
2048 buffer_reset(&vs->input);
2049 buffer_reset(&vs->output);
2050 vs->need_update = 0;
2051 #if CONFIG_VNC_TLS
2052 if (vs->tls_session) {
2053 gnutls_deinit(vs->tls_session);
2054 vs->tls_session = NULL;
2056 vs->wiremode = VNC_WIREMODE_CLEAR;
2057 #endif /* CONFIG_VNC_TLS */
2059 vs->auth = VNC_AUTH_INVALID;
2060 #if CONFIG_VNC_TLS
2061 vs->subauth = VNC_AUTH_INVALID;
2062 vs->x509verify = 0;
2063 #endif
2066 int vnc_display_password(DisplayState *ds, const char *password)
2068 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2070 if (vs->password) {
2071 qemu_free(vs->password);
2072 vs->password = NULL;
2074 if (password && password[0]) {
2075 if (!(vs->password = qemu_strdup(password)))
2076 return -1;
2079 return 0;
2082 int vnc_display_open(DisplayState *ds, const char *display)
2084 struct sockaddr *addr;
2085 struct sockaddr_in iaddr;
2086 #ifndef _WIN32
2087 struct sockaddr_un uaddr;
2088 #endif
2089 int reuse_addr, ret;
2090 socklen_t addrlen;
2091 const char *p;
2092 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2093 const char *options;
2094 int password = 0;
2095 int reverse = 0;
2096 #if CONFIG_VNC_TLS
2097 int tls = 0, x509 = 0;
2098 #endif
2100 vnc_display_close(ds);
2101 if (strcmp(display, "none") == 0)
2102 return 0;
2104 if (!(vs->display = strdup(display)))
2105 return -1;
2107 options = display;
2108 while ((options = strchr(options, ','))) {
2109 options++;
2110 if (strncmp(options, "password", 8) == 0) {
2111 password = 1; /* Require password auth */
2112 } else if (strncmp(options, "reverse", 7) == 0) {
2113 reverse = 1;
2114 #if CONFIG_VNC_TLS
2115 } else if (strncmp(options, "tls", 3) == 0) {
2116 tls = 1; /* Require TLS */
2117 } else if (strncmp(options, "x509", 4) == 0) {
2118 char *start, *end;
2119 x509 = 1; /* Require x509 certificates */
2120 if (strncmp(options, "x509verify", 10) == 0)
2121 vs->x509verify = 1; /* ...and verify client certs */
2123 /* Now check for 'x509=/some/path' postfix
2124 * and use that to setup x509 certificate/key paths */
2125 start = strchr(options, '=');
2126 end = strchr(options, ',');
2127 if (start && (!end || (start < end))) {
2128 int len = end ? end-(start+1) : strlen(start+1);
2129 char *path = qemu_malloc(len+1);
2130 strncpy(path, start+1, len);
2131 path[len] = '\0';
2132 VNC_DEBUG("Trying certificate path '%s'\n", path);
2133 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2134 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2135 qemu_free(path);
2136 qemu_free(vs->display);
2137 vs->display = NULL;
2138 return -1;
2140 qemu_free(path);
2141 } else {
2142 fprintf(stderr, "No certificate path provided\n");
2143 qemu_free(vs->display);
2144 vs->display = NULL;
2145 return -1;
2147 #endif
2151 if (password) {
2152 #if CONFIG_VNC_TLS
2153 if (tls) {
2154 vs->auth = VNC_AUTH_VENCRYPT;
2155 if (x509) {
2156 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2157 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2158 } else {
2159 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2160 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2162 } else {
2163 #endif
2164 VNC_DEBUG("Initializing VNC server with password auth\n");
2165 vs->auth = VNC_AUTH_VNC;
2166 #if CONFIG_VNC_TLS
2167 vs->subauth = VNC_AUTH_INVALID;
2169 #endif
2170 } else {
2171 #if CONFIG_VNC_TLS
2172 if (tls) {
2173 vs->auth = VNC_AUTH_VENCRYPT;
2174 if (x509) {
2175 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2176 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2177 } else {
2178 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2179 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2181 } else {
2182 #endif
2183 VNC_DEBUG("Initializing VNC server with no auth\n");
2184 vs->auth = VNC_AUTH_NONE;
2185 #if CONFIG_VNC_TLS
2186 vs->subauth = VNC_AUTH_INVALID;
2188 #endif
2190 #ifndef _WIN32
2191 if (strstart(display, "unix:", &p)) {
2192 addr = (struct sockaddr *)&uaddr;
2193 addrlen = sizeof(uaddr);
2195 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2196 if (vs->lsock == -1) {
2197 fprintf(stderr, "Could not create socket\n");
2198 free(vs->display);
2199 vs->display = NULL;
2200 return -1;
2203 uaddr.sun_family = AF_UNIX;
2204 memset(uaddr.sun_path, 0, 108);
2205 snprintf(uaddr.sun_path, 108, "%s", p);
2207 if (!reverse) {
2208 unlink(uaddr.sun_path);
2210 } else
2211 #endif
2213 addr = (struct sockaddr *)&iaddr;
2214 addrlen = sizeof(iaddr);
2216 if (parse_host_port(&iaddr, display) < 0) {
2217 fprintf(stderr, "Could not parse VNC address\n");
2218 free(vs->display);
2219 vs->display = NULL;
2220 return -1;
2223 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900));
2225 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2226 if (vs->lsock == -1) {
2227 fprintf(stderr, "Could not create socket\n");
2228 free(vs->display);
2229 vs->display = NULL;
2230 return -1;
2233 reuse_addr = 1;
2234 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2235 (const char *)&reuse_addr, sizeof(reuse_addr));
2236 if (ret == -1) {
2237 fprintf(stderr, "setsockopt() failed\n");
2238 close(vs->lsock);
2239 vs->lsock = -1;
2240 free(vs->display);
2241 vs->display = NULL;
2242 return -1;
2246 if (reverse) {
2247 if (connect(vs->lsock, addr, addrlen) == -1) {
2248 fprintf(stderr, "Connection to VNC client failed\n");
2249 close(vs->lsock);
2250 vs->lsock = -1;
2251 free(vs->display);
2252 vs->display = NULL;
2253 return -1;
2254 } else {
2255 vs->csock = vs->lsock;
2256 vs->lsock = -1;
2257 vnc_connect(vs);
2258 return 0;
2262 if (bind(vs->lsock, addr, addrlen) == -1) {
2263 fprintf(stderr, "bind() failed\n");
2264 close(vs->lsock);
2265 vs->lsock = -1;
2266 free(vs->display);
2267 vs->display = NULL;
2268 return -1;
2271 if (listen(vs->lsock, 1) == -1) {
2272 fprintf(stderr, "listen() failed\n");
2273 close(vs->lsock);
2274 vs->lsock = -1;
2275 free(vs->display);
2276 vs->display = NULL;
2277 return -1;
2280 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);