kvm: testsuite: add implement putc() and exit() mmop registers
[qemu-kvm/fedora.git] / vnc.c
blob1a96857402d73886eba75012c194a50ff1faf775
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 vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
511 /* Walk through the dirty map and eliminate tiles that
512 really aren't dirty */
513 row = vs->ds->data;
514 old_row = vs->old_data;
516 for (y = 0; y < vs->height; y++) {
517 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
518 int x;
519 uint8_t *ptr;
520 char *old_ptr;
522 ptr = row;
523 old_ptr = (char*)old_row;
525 for (x = 0; x < vs->ds->width; x += 16) {
526 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
527 vnc_clear_bit(vs->dirty_row[y], (x / 16));
528 } else {
529 has_dirty = 1;
530 memcpy(old_ptr, ptr, 16 * vs->depth);
533 ptr += 16 * vs->depth;
534 old_ptr += 16 * vs->depth;
538 row += vs->ds->linesize;
539 old_row += vs->ds->linesize;
542 if (!has_dirty) {
543 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
544 return;
547 /* Count rectangles */
548 n_rectangles = 0;
549 vnc_write_u8(vs, 0); /* msg id */
550 vnc_write_u8(vs, 0);
551 saved_offset = vs->output.offset;
552 vnc_write_u16(vs, 0);
554 for (y = 0; y < vs->height; y++) {
555 int x;
556 int last_x = -1;
557 for (x = 0; x < vs->width / 16; x++) {
558 if (vnc_get_bit(vs->dirty_row[y], x)) {
559 if (last_x == -1) {
560 last_x = x;
562 vnc_clear_bit(vs->dirty_row[y], x);
563 } else {
564 if (last_x != -1) {
565 int h = find_dirty_height(vs, y, last_x, x);
566 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
567 n_rectangles++;
569 last_x = -1;
572 if (last_x != -1) {
573 int h = find_dirty_height(vs, y, last_x, x);
574 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
575 n_rectangles++;
578 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
579 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
580 vnc_flush(vs);
583 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
586 static void vnc_timer_init(VncState *vs)
588 if (vs->timer == NULL) {
589 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
590 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
594 static void vnc_dpy_refresh(DisplayState *ds)
596 VncState *vs = ds->opaque;
597 vnc_timer_init(vs);
598 vga_hw_update();
601 static int vnc_listen_poll(void *opaque)
603 VncState *vs = opaque;
604 if (vs->csock == -1)
605 return 1;
606 return 0;
609 static void buffer_reserve(Buffer *buffer, size_t len)
611 if ((buffer->capacity - buffer->offset) < len) {
612 buffer->capacity += (len + 1024);
613 buffer->buffer = realloc(buffer->buffer, buffer->capacity);
614 if (buffer->buffer == NULL) {
615 fprintf(stderr, "vnc: out of memory\n");
616 exit(1);
621 static int buffer_empty(Buffer *buffer)
623 return buffer->offset == 0;
626 static uint8_t *buffer_end(Buffer *buffer)
628 return buffer->buffer + buffer->offset;
631 static void buffer_reset(Buffer *buffer)
633 buffer->offset = 0;
636 static void buffer_append(Buffer *buffer, const void *data, size_t len)
638 memcpy(buffer->buffer + buffer->offset, data, len);
639 buffer->offset += len;
642 static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
644 if (ret == 0 || ret == -1) {
645 if (ret == -1 && (last_errno == EINTR || last_errno == EAGAIN))
646 return 0;
648 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
649 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
650 closesocket(vs->csock);
651 vs->csock = -1;
652 buffer_reset(&vs->input);
653 buffer_reset(&vs->output);
654 vs->need_update = 0;
655 #if CONFIG_VNC_TLS
656 if (vs->tls_session) {
657 gnutls_deinit(vs->tls_session);
658 vs->tls_session = NULL;
660 vs->wiremode = VNC_WIREMODE_CLEAR;
661 #endif /* CONFIG_VNC_TLS */
662 return 0;
664 return ret;
667 static void vnc_client_error(VncState *vs)
669 vnc_client_io_error(vs, -1, EINVAL);
672 static void vnc_client_write(void *opaque)
674 long ret;
675 VncState *vs = opaque;
677 #if CONFIG_VNC_TLS
678 if (vs->tls_session) {
679 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
680 if (ret < 0) {
681 if (ret == GNUTLS_E_AGAIN)
682 errno = EAGAIN;
683 else
684 errno = EIO;
685 ret = -1;
687 } else
688 #endif /* CONFIG_VNC_TLS */
689 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
690 ret = vnc_client_io_error(vs, ret, socket_error());
691 if (!ret)
692 return;
694 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
695 vs->output.offset -= ret;
697 if (vs->output.offset == 0) {
698 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
702 static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
704 vs->read_handler = func;
705 vs->read_handler_expect = expecting;
708 static void vnc_client_read(void *opaque)
710 VncState *vs = opaque;
711 long ret;
713 buffer_reserve(&vs->input, 4096);
715 #if CONFIG_VNC_TLS
716 if (vs->tls_session) {
717 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
718 if (ret < 0) {
719 if (ret == GNUTLS_E_AGAIN)
720 errno = EAGAIN;
721 else
722 errno = EIO;
723 ret = -1;
725 } else
726 #endif /* CONFIG_VNC_TLS */
727 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
728 ret = vnc_client_io_error(vs, ret, socket_error());
729 if (!ret)
730 return;
732 vs->input.offset += ret;
734 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
735 size_t len = vs->read_handler_expect;
736 int ret;
738 ret = vs->read_handler(vs, vs->input.buffer, len);
739 if (vs->csock == -1)
740 return;
742 if (!ret) {
743 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
744 vs->input.offset -= len;
745 } else {
746 vs->read_handler_expect = ret;
751 static void vnc_write(VncState *vs, const void *data, size_t len)
753 buffer_reserve(&vs->output, len);
755 if (buffer_empty(&vs->output)) {
756 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
759 buffer_append(&vs->output, data, len);
762 static void vnc_write_s32(VncState *vs, int32_t value)
764 vnc_write_u32(vs, *(uint32_t *)&value);
767 static void vnc_write_u32(VncState *vs, uint32_t value)
769 uint8_t buf[4];
771 buf[0] = (value >> 24) & 0xFF;
772 buf[1] = (value >> 16) & 0xFF;
773 buf[2] = (value >> 8) & 0xFF;
774 buf[3] = value & 0xFF;
776 vnc_write(vs, buf, 4);
779 static void vnc_write_u16(VncState *vs, uint16_t value)
781 uint8_t buf[2];
783 buf[0] = (value >> 8) & 0xFF;
784 buf[1] = value & 0xFF;
786 vnc_write(vs, buf, 2);
789 static void vnc_write_u8(VncState *vs, uint8_t value)
791 vnc_write(vs, (char *)&value, 1);
794 static void vnc_flush(VncState *vs)
796 if (vs->output.offset)
797 vnc_client_write(vs);
800 static uint8_t read_u8(uint8_t *data, size_t offset)
802 return data[offset];
805 static uint16_t read_u16(uint8_t *data, size_t offset)
807 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
810 static int32_t read_s32(uint8_t *data, size_t offset)
812 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
813 (data[offset + 2] << 8) | data[offset + 3]);
816 static uint32_t read_u32(uint8_t *data, size_t offset)
818 return ((data[offset] << 24) | (data[offset + 1] << 16) |
819 (data[offset + 2] << 8) | data[offset + 3]);
822 #if CONFIG_VNC_TLS
823 static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
824 const void *data,
825 size_t len) {
826 struct VncState *vs = (struct VncState *)transport;
827 int ret;
829 retry:
830 ret = send(vs->csock, data, len, 0);
831 if (ret < 0) {
832 if (errno == EINTR)
833 goto retry;
834 return -1;
836 return ret;
840 static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
841 void *data,
842 size_t len) {
843 struct VncState *vs = (struct VncState *)transport;
844 int ret;
846 retry:
847 ret = recv(vs->csock, data, len, 0);
848 if (ret < 0) {
849 if (errno == EINTR)
850 goto retry;
851 return -1;
853 return ret;
855 #endif /* CONFIG_VNC_TLS */
857 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
861 static void check_pointer_type_change(VncState *vs, int absolute)
863 if (vs->has_pointer_type_change && vs->absolute != absolute) {
864 vnc_write_u8(vs, 0);
865 vnc_write_u8(vs, 0);
866 vnc_write_u16(vs, 1);
867 vnc_framebuffer_update(vs, absolute, 0,
868 vs->ds->width, vs->ds->height, -257);
869 vnc_flush(vs);
871 vs->absolute = absolute;
874 static void pointer_event(VncState *vs, int button_mask, int x, int y)
876 int buttons = 0;
877 int dz = 0;
879 if (button_mask & 0x01)
880 buttons |= MOUSE_EVENT_LBUTTON;
881 if (button_mask & 0x02)
882 buttons |= MOUSE_EVENT_MBUTTON;
883 if (button_mask & 0x04)
884 buttons |= MOUSE_EVENT_RBUTTON;
885 if (button_mask & 0x08)
886 dz = -1;
887 if (button_mask & 0x10)
888 dz = 1;
890 if (vs->absolute) {
891 kbd_mouse_event(x * 0x7FFF / vs->ds->width,
892 y * 0x7FFF / vs->ds->height,
893 dz, buttons);
894 } else if (vs->has_pointer_type_change) {
895 x -= 0x7FFF;
896 y -= 0x7FFF;
898 kbd_mouse_event(x, y, dz, buttons);
899 } else {
900 if (vs->last_x != -1)
901 kbd_mouse_event(x - vs->last_x,
902 y - vs->last_y,
903 dz, buttons);
904 vs->last_x = x;
905 vs->last_y = y;
908 check_pointer_type_change(vs, kbd_mouse_is_absolute());
911 static void reset_keys(VncState *vs)
913 int i;
914 for(i = 0; i < 256; i++) {
915 if (vs->modifiers_state[i]) {
916 if (i & 0x80)
917 kbd_put_keycode(0xe0);
918 kbd_put_keycode(i | 0x80);
919 vs->modifiers_state[i] = 0;
924 static void press_key(VncState *vs, int keysym)
926 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
927 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
930 static void do_key_event(VncState *vs, int down, uint32_t sym)
932 int keycode;
934 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
936 /* QEMU console switch */
937 switch(keycode) {
938 case 0x2a: /* Left Shift */
939 case 0x36: /* Right Shift */
940 case 0x1d: /* Left CTRL */
941 case 0x9d: /* Right CTRL */
942 case 0x38: /* Left ALT */
943 case 0xb8: /* Right ALT */
944 if (down)
945 vs->modifiers_state[keycode] = 1;
946 else
947 vs->modifiers_state[keycode] = 0;
948 break;
949 case 0x02 ... 0x0a: /* '1' to '9' keys */
950 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
951 /* Reset the modifiers sent to the current console */
952 reset_keys(vs);
953 console_select(keycode - 0x02);
954 return;
956 break;
957 case 0x45: /* NumLock */
958 if (!down)
959 vs->modifiers_state[keycode] ^= 1;
960 break;
963 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
964 /* If the numlock state needs to change then simulate an additional
965 keypress before sending this one. This will happen if the user
966 toggles numlock away from the VNC window.
968 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
969 if (!vs->modifiers_state[0x45]) {
970 vs->modifiers_state[0x45] = 1;
971 press_key(vs, 0xff7f);
973 } else {
974 if (vs->modifiers_state[0x45]) {
975 vs->modifiers_state[0x45] = 0;
976 press_key(vs, 0xff7f);
981 if (is_graphic_console()) {
982 if (keycode & 0x80)
983 kbd_put_keycode(0xe0);
984 if (down)
985 kbd_put_keycode(keycode & 0x7f);
986 else
987 kbd_put_keycode(keycode | 0x80);
988 } else {
989 /* QEMU console emulation */
990 if (down) {
991 switch (keycode) {
992 case 0x2a: /* Left Shift */
993 case 0x36: /* Right Shift */
994 case 0x1d: /* Left CTRL */
995 case 0x9d: /* Right CTRL */
996 case 0x38: /* Left ALT */
997 case 0xb8: /* Right ALT */
998 break;
999 case 0xc8:
1000 kbd_put_keysym(QEMU_KEY_UP);
1001 break;
1002 case 0xd0:
1003 kbd_put_keysym(QEMU_KEY_DOWN);
1004 break;
1005 case 0xcb:
1006 kbd_put_keysym(QEMU_KEY_LEFT);
1007 break;
1008 case 0xcd:
1009 kbd_put_keysym(QEMU_KEY_RIGHT);
1010 break;
1011 case 0xd3:
1012 kbd_put_keysym(QEMU_KEY_DELETE);
1013 break;
1014 case 0xc7:
1015 kbd_put_keysym(QEMU_KEY_HOME);
1016 break;
1017 case 0xcf:
1018 kbd_put_keysym(QEMU_KEY_END);
1019 break;
1020 case 0xc9:
1021 kbd_put_keysym(QEMU_KEY_PAGEUP);
1022 break;
1023 case 0xd1:
1024 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1025 break;
1026 default:
1027 kbd_put_keysym(sym);
1028 break;
1034 static void key_event(VncState *vs, int down, uint32_t sym)
1036 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1037 sym = sym - 'A' + 'a';
1038 do_key_event(vs, down, sym);
1041 static void framebuffer_update_request(VncState *vs, int incremental,
1042 int x_position, int y_position,
1043 int w, int h)
1045 if (x_position > vs->ds->width)
1046 x_position = vs->ds->width;
1047 if (y_position > vs->ds->height)
1048 y_position = vs->ds->height;
1049 if (x_position + w >= vs->ds->width)
1050 w = vs->ds->width - x_position;
1051 if (y_position + h >= vs->ds->height)
1052 h = vs->ds->height - y_position;
1054 int i;
1055 vs->need_update = 1;
1056 if (!incremental) {
1057 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1059 for (i = 0; i < h; i++) {
1060 vnc_set_bits(vs->dirty_row[y_position + i],
1061 (vs->ds->width / 16), VNC_DIRTY_WORDS);
1062 memset(old_row, 42, vs->ds->width * vs->depth);
1063 old_row += vs->ds->linesize;
1068 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1070 int i;
1072 vs->has_hextile = 0;
1073 vs->has_resize = 0;
1074 vs->has_pointer_type_change = 0;
1075 vs->absolute = -1;
1076 vs->ds->dpy_copy = NULL;
1078 for (i = n_encodings - 1; i >= 0; i--) {
1079 switch (encodings[i]) {
1080 case 0: /* Raw */
1081 vs->has_hextile = 0;
1082 break;
1083 case 1: /* CopyRect */
1084 vs->ds->dpy_copy = vnc_copy;
1085 break;
1086 case 5: /* Hextile */
1087 vs->has_hextile = 1;
1088 break;
1089 case -223: /* DesktopResize */
1090 vs->has_resize = 1;
1091 break;
1092 case -257:
1093 vs->has_pointer_type_change = 1;
1094 break;
1095 default:
1096 break;
1100 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1103 static int compute_nbits(unsigned int val)
1105 int n;
1106 n = 0;
1107 while (val != 0) {
1108 n++;
1109 val >>= 1;
1111 return n;
1114 static void set_pixel_format(VncState *vs,
1115 int bits_per_pixel, int depth,
1116 int big_endian_flag, int true_color_flag,
1117 int red_max, int green_max, int blue_max,
1118 int red_shift, int green_shift, int blue_shift)
1120 int host_big_endian_flag;
1122 #ifdef WORDS_BIGENDIAN
1123 host_big_endian_flag = 1;
1124 #else
1125 host_big_endian_flag = 0;
1126 #endif
1127 if (!true_color_flag) {
1128 fail:
1129 vnc_client_error(vs);
1130 return;
1132 if (bits_per_pixel == 32 &&
1133 host_big_endian_flag == big_endian_flag &&
1134 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1135 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1136 vs->depth = 4;
1137 vs->write_pixels = vnc_write_pixels_copy;
1138 vs->send_hextile_tile = send_hextile_tile_32;
1139 } else
1140 if (bits_per_pixel == 16 &&
1141 host_big_endian_flag == big_endian_flag &&
1142 red_max == 31 && green_max == 63 && blue_max == 31 &&
1143 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1144 vs->depth = 2;
1145 vs->write_pixels = vnc_write_pixels_copy;
1146 vs->send_hextile_tile = send_hextile_tile_16;
1147 } else
1148 if (bits_per_pixel == 8 &&
1149 red_max == 7 && green_max == 7 && blue_max == 3 &&
1150 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1151 vs->depth = 1;
1152 vs->write_pixels = vnc_write_pixels_copy;
1153 vs->send_hextile_tile = send_hextile_tile_8;
1154 } else
1156 /* generic and slower case */
1157 if (bits_per_pixel != 8 &&
1158 bits_per_pixel != 16 &&
1159 bits_per_pixel != 32)
1160 goto fail;
1161 vs->depth = 4;
1162 vs->red_shift = red_shift;
1163 vs->red_max = red_max;
1164 vs->red_shift1 = 24 - compute_nbits(red_max);
1165 vs->green_shift = green_shift;
1166 vs->green_max = green_max;
1167 vs->green_shift1 = 16 - compute_nbits(green_max);
1168 vs->blue_shift = blue_shift;
1169 vs->blue_max = blue_max;
1170 vs->blue_shift1 = 8 - compute_nbits(blue_max);
1171 vs->pix_bpp = bits_per_pixel / 8;
1172 vs->pix_big_endian = big_endian_flag;
1173 vs->write_pixels = vnc_write_pixels_generic;
1174 vs->send_hextile_tile = send_hextile_tile_generic;
1177 vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1178 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1179 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
1181 vga_hw_invalidate();
1182 vga_hw_update();
1185 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1187 int i;
1188 uint16_t limit;
1190 switch (data[0]) {
1191 case 0:
1192 if (len == 1)
1193 return 20;
1195 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1196 read_u8(data, 6), read_u8(data, 7),
1197 read_u16(data, 8), read_u16(data, 10),
1198 read_u16(data, 12), read_u8(data, 14),
1199 read_u8(data, 15), read_u8(data, 16));
1200 break;
1201 case 2:
1202 if (len == 1)
1203 return 4;
1205 if (len == 4)
1206 return 4 + (read_u16(data, 2) * 4);
1208 limit = read_u16(data, 2);
1209 for (i = 0; i < limit; i++) {
1210 int32_t val = read_s32(data, 4 + (i * 4));
1211 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1214 set_encodings(vs, (int32_t *)(data + 4), limit);
1215 break;
1216 case 3:
1217 if (len == 1)
1218 return 10;
1220 framebuffer_update_request(vs,
1221 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1222 read_u16(data, 6), read_u16(data, 8));
1223 break;
1224 case 4:
1225 if (len == 1)
1226 return 8;
1228 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1229 break;
1230 case 5:
1231 if (len == 1)
1232 return 6;
1234 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1235 break;
1236 case 6:
1237 if (len == 1)
1238 return 8;
1240 if (len == 8) {
1241 uint32_t dlen = read_u32(data, 4);
1242 if (dlen > 0)
1243 return 8 + dlen;
1246 client_cut_text(vs, read_u32(data, 4), data + 8);
1247 break;
1248 default:
1249 printf("Msg: %d\n", data[0]);
1250 vnc_client_error(vs);
1251 break;
1254 vnc_read_when(vs, protocol_client_msg, 1);
1255 return 0;
1258 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1260 char pad[3] = { 0, 0, 0 };
1261 char buf[1024];
1262 int size;
1263 char prog[30] = "QEMU";
1265 vs->width = vs->ds->width;
1266 vs->height = vs->ds->height;
1267 vnc_write_u16(vs, vs->ds->width);
1268 vnc_write_u16(vs, vs->ds->height);
1270 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1271 vnc_write_u8(vs, vs->depth * 8); /* depth */
1272 #ifdef WORDS_BIGENDIAN
1273 vnc_write_u8(vs, 1); /* big-endian-flag */
1274 #else
1275 vnc_write_u8(vs, 0); /* big-endian-flag */
1276 #endif
1277 vnc_write_u8(vs, 1); /* true-color-flag */
1278 if (vs->depth == 4) {
1279 vnc_write_u16(vs, 0xFF); /* red-max */
1280 vnc_write_u16(vs, 0xFF); /* green-max */
1281 vnc_write_u16(vs, 0xFF); /* blue-max */
1282 vnc_write_u8(vs, 16); /* red-shift */
1283 vnc_write_u8(vs, 8); /* green-shift */
1284 vnc_write_u8(vs, 0); /* blue-shift */
1285 vs->send_hextile_tile = send_hextile_tile_32;
1286 } else if (vs->depth == 2) {
1287 vnc_write_u16(vs, 31); /* red-max */
1288 vnc_write_u16(vs, 63); /* green-max */
1289 vnc_write_u16(vs, 31); /* blue-max */
1290 vnc_write_u8(vs, 11); /* red-shift */
1291 vnc_write_u8(vs, 5); /* green-shift */
1292 vnc_write_u8(vs, 0); /* blue-shift */
1293 vs->send_hextile_tile = send_hextile_tile_16;
1294 } else if (vs->depth == 1) {
1295 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1296 vnc_write_u16(vs, 7); /* red-max */
1297 vnc_write_u16(vs, 7); /* green-max */
1298 vnc_write_u16(vs, 3); /* blue-max */
1299 vnc_write_u8(vs, 5); /* red-shift */
1300 vnc_write_u8(vs, 2); /* green-shift */
1301 vnc_write_u8(vs, 0); /* blue-shift */
1302 vs->send_hextile_tile = send_hextile_tile_8;
1304 vs->write_pixels = vnc_write_pixels_copy;
1306 vnc_write(vs, pad, 3); /* padding */
1308 decorate_application_name((char *)prog, sizeof prog);
1310 if (qemu_name)
1311 size = snprintf(buf, sizeof(buf), "%s (%s)", prog, qemu_name);
1312 else
1313 size = snprintf(buf, sizeof(buf), "%s", prog);
1315 vnc_write_u32(vs, size);
1316 vnc_write(vs, buf, size);
1317 vnc_flush(vs);
1319 vnc_read_when(vs, protocol_client_msg, 1);
1321 return 0;
1324 static void make_challenge(VncState *vs)
1326 int i;
1328 srand(time(NULL)+getpid()+getpid()*987654+rand());
1330 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1331 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1334 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1336 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1337 int i, j, pwlen;
1338 unsigned char key[8];
1340 if (!vs->password || !vs->password[0]) {
1341 VNC_DEBUG("No password configured on server");
1342 vnc_write_u32(vs, 1); /* Reject auth */
1343 if (vs->minor >= 8) {
1344 static const char err[] = "Authentication failed";
1345 vnc_write_u32(vs, sizeof(err));
1346 vnc_write(vs, err, sizeof(err));
1348 vnc_flush(vs);
1349 vnc_client_error(vs);
1350 return 0;
1353 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1355 /* Calculate the expected challenge response */
1356 pwlen = strlen(vs->password);
1357 for (i=0; i<sizeof(key); i++)
1358 key[i] = i<pwlen ? vs->password[i] : 0;
1359 deskey(key, EN0);
1360 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1361 des(response+j, response+j);
1363 /* Compare expected vs actual challenge response */
1364 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1365 VNC_DEBUG("Client challenge reponse did not match\n");
1366 vnc_write_u32(vs, 1); /* Reject auth */
1367 if (vs->minor >= 8) {
1368 static const char err[] = "Authentication failed";
1369 vnc_write_u32(vs, sizeof(err));
1370 vnc_write(vs, err, sizeof(err));
1372 vnc_flush(vs);
1373 vnc_client_error(vs);
1374 } else {
1375 VNC_DEBUG("Accepting VNC challenge response\n");
1376 vnc_write_u32(vs, 0); /* Accept auth */
1377 vnc_flush(vs);
1379 vnc_read_when(vs, protocol_client_init, 1);
1381 return 0;
1384 static int start_auth_vnc(VncState *vs)
1386 make_challenge(vs);
1387 /* Send client a 'random' challenge */
1388 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1389 vnc_flush(vs);
1391 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1392 return 0;
1396 #if CONFIG_VNC_TLS
1397 #define DH_BITS 1024
1398 static gnutls_dh_params_t dh_params;
1400 static int vnc_tls_initialize(void)
1402 static int tlsinitialized = 0;
1404 if (tlsinitialized)
1405 return 1;
1407 if (gnutls_global_init () < 0)
1408 return 0;
1410 /* XXX ought to re-generate diffie-hellmen params periodically */
1411 if (gnutls_dh_params_init (&dh_params) < 0)
1412 return 0;
1413 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1414 return 0;
1416 #if _VNC_DEBUG == 2
1417 gnutls_global_set_log_level(10);
1418 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1419 #endif
1421 tlsinitialized = 1;
1423 return 1;
1426 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1428 gnutls_anon_server_credentials anon_cred;
1429 int ret;
1431 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1432 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1433 return NULL;
1436 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1438 return anon_cred;
1442 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1444 gnutls_certificate_credentials_t x509_cred;
1445 int ret;
1447 if (!vs->x509cacert) {
1448 VNC_DEBUG("No CA x509 certificate specified\n");
1449 return NULL;
1451 if (!vs->x509cert) {
1452 VNC_DEBUG("No server x509 certificate specified\n");
1453 return NULL;
1455 if (!vs->x509key) {
1456 VNC_DEBUG("No server private key specified\n");
1457 return NULL;
1460 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1461 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1462 return NULL;
1464 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1465 vs->x509cacert,
1466 GNUTLS_X509_FMT_PEM)) < 0) {
1467 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1468 gnutls_certificate_free_credentials(x509_cred);
1469 return NULL;
1472 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1473 vs->x509cert,
1474 vs->x509key,
1475 GNUTLS_X509_FMT_PEM)) < 0) {
1476 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1477 gnutls_certificate_free_credentials(x509_cred);
1478 return NULL;
1481 if (vs->x509cacrl) {
1482 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1483 vs->x509cacrl,
1484 GNUTLS_X509_FMT_PEM)) < 0) {
1485 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1486 gnutls_certificate_free_credentials(x509_cred);
1487 return NULL;
1491 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1493 return x509_cred;
1496 static int vnc_validate_certificate(struct VncState *vs)
1498 int ret;
1499 unsigned int status;
1500 const gnutls_datum_t *certs;
1501 unsigned int nCerts, i;
1502 time_t now;
1504 VNC_DEBUG("Validating client certificate\n");
1505 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1506 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1507 return -1;
1510 if ((now = time(NULL)) == ((time_t)-1)) {
1511 return -1;
1514 if (status != 0) {
1515 if (status & GNUTLS_CERT_INVALID)
1516 VNC_DEBUG("The certificate is not trusted.\n");
1518 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1519 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1521 if (status & GNUTLS_CERT_REVOKED)
1522 VNC_DEBUG("The certificate has been revoked.\n");
1524 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1525 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1527 return -1;
1528 } else {
1529 VNC_DEBUG("Certificate is valid!\n");
1532 /* Only support x509 for now */
1533 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1534 return -1;
1536 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1537 return -1;
1539 for (i = 0 ; i < nCerts ; i++) {
1540 gnutls_x509_crt_t cert;
1541 VNC_DEBUG ("Checking certificate chain %d\n", i);
1542 if (gnutls_x509_crt_init (&cert) < 0)
1543 return -1;
1545 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1546 gnutls_x509_crt_deinit (cert);
1547 return -1;
1550 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1551 VNC_DEBUG("The certificate has expired\n");
1552 gnutls_x509_crt_deinit (cert);
1553 return -1;
1556 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1557 VNC_DEBUG("The certificate is not yet activated\n");
1558 gnutls_x509_crt_deinit (cert);
1559 return -1;
1562 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1563 VNC_DEBUG("The certificate is not yet activated\n");
1564 gnutls_x509_crt_deinit (cert);
1565 return -1;
1568 gnutls_x509_crt_deinit (cert);
1571 return 0;
1575 static int start_auth_vencrypt_subauth(VncState *vs)
1577 switch (vs->subauth) {
1578 case VNC_AUTH_VENCRYPT_TLSNONE:
1579 case VNC_AUTH_VENCRYPT_X509NONE:
1580 VNC_DEBUG("Accept TLS auth none\n");
1581 vnc_write_u32(vs, 0); /* Accept auth completion */
1582 vnc_read_when(vs, protocol_client_init, 1);
1583 break;
1585 case VNC_AUTH_VENCRYPT_TLSVNC:
1586 case VNC_AUTH_VENCRYPT_X509VNC:
1587 VNC_DEBUG("Start TLS auth VNC\n");
1588 return start_auth_vnc(vs);
1590 default: /* Should not be possible, but just in case */
1591 VNC_DEBUG("Reject auth %d\n", vs->auth);
1592 vnc_write_u8(vs, 1);
1593 if (vs->minor >= 8) {
1594 static const char err[] = "Unsupported authentication type";
1595 vnc_write_u32(vs, sizeof(err));
1596 vnc_write(vs, err, sizeof(err));
1598 vnc_client_error(vs);
1601 return 0;
1604 static void vnc_handshake_io(void *opaque);
1606 static int vnc_continue_handshake(struct VncState *vs) {
1607 int ret;
1609 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1610 if (!gnutls_error_is_fatal(ret)) {
1611 VNC_DEBUG("Handshake interrupted (blocking)\n");
1612 if (!gnutls_record_get_direction(vs->tls_session))
1613 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1614 else
1615 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1616 return 0;
1618 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1619 vnc_client_error(vs);
1620 return -1;
1623 if (vs->x509verify) {
1624 if (vnc_validate_certificate(vs) < 0) {
1625 VNC_DEBUG("Client verification failed\n");
1626 vnc_client_error(vs);
1627 return -1;
1628 } else {
1629 VNC_DEBUG("Client verification passed\n");
1633 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1634 vs->wiremode = VNC_WIREMODE_TLS;
1635 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1637 return start_auth_vencrypt_subauth(vs);
1640 static void vnc_handshake_io(void *opaque) {
1641 struct VncState *vs = (struct VncState *)opaque;
1643 VNC_DEBUG("Handshake IO continue\n");
1644 vnc_continue_handshake(vs);
1647 #define NEED_X509_AUTH(vs) \
1648 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1649 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1650 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1653 static int vnc_start_tls(struct VncState *vs) {
1654 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1655 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1656 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1657 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1659 VNC_DEBUG("Do TLS setup\n");
1660 if (vnc_tls_initialize() < 0) {
1661 VNC_DEBUG("Failed to init TLS\n");
1662 vnc_client_error(vs);
1663 return -1;
1665 if (vs->tls_session == NULL) {
1666 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1667 vnc_client_error(vs);
1668 return -1;
1671 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1672 gnutls_deinit(vs->tls_session);
1673 vs->tls_session = NULL;
1674 vnc_client_error(vs);
1675 return -1;
1678 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1679 gnutls_deinit(vs->tls_session);
1680 vs->tls_session = NULL;
1681 vnc_client_error(vs);
1682 return -1;
1685 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1686 gnutls_deinit(vs->tls_session);
1687 vs->tls_session = NULL;
1688 vnc_client_error(vs);
1689 return -1;
1692 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1693 gnutls_deinit(vs->tls_session);
1694 vs->tls_session = NULL;
1695 vnc_client_error(vs);
1696 return -1;
1699 if (NEED_X509_AUTH(vs)) {
1700 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1701 if (!x509_cred) {
1702 gnutls_deinit(vs->tls_session);
1703 vs->tls_session = NULL;
1704 vnc_client_error(vs);
1705 return -1;
1707 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1708 gnutls_deinit(vs->tls_session);
1709 vs->tls_session = NULL;
1710 gnutls_certificate_free_credentials(x509_cred);
1711 vnc_client_error(vs);
1712 return -1;
1714 if (vs->x509verify) {
1715 VNC_DEBUG("Requesting a client certificate\n");
1716 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1719 } else {
1720 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1721 if (!anon_cred) {
1722 gnutls_deinit(vs->tls_session);
1723 vs->tls_session = NULL;
1724 vnc_client_error(vs);
1725 return -1;
1727 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1728 gnutls_deinit(vs->tls_session);
1729 vs->tls_session = NULL;
1730 gnutls_anon_free_server_credentials(anon_cred);
1731 vnc_client_error(vs);
1732 return -1;
1736 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1737 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1738 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1741 VNC_DEBUG("Start TLS handshake process\n");
1742 return vnc_continue_handshake(vs);
1745 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
1747 int auth = read_u32(data, 0);
1749 if (auth != vs->subauth) {
1750 VNC_DEBUG("Rejecting auth %d\n", auth);
1751 vnc_write_u8(vs, 0); /* Reject auth */
1752 vnc_flush(vs);
1753 vnc_client_error(vs);
1754 } else {
1755 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1756 vnc_write_u8(vs, 1); /* Accept auth */
1757 vnc_flush(vs);
1759 if (vnc_start_tls(vs) < 0) {
1760 VNC_DEBUG("Failed to complete TLS\n");
1761 return 0;
1764 if (vs->wiremode == VNC_WIREMODE_TLS) {
1765 VNC_DEBUG("Starting VeNCrypt subauth\n");
1766 return start_auth_vencrypt_subauth(vs);
1767 } else {
1768 VNC_DEBUG("TLS handshake blocked\n");
1769 return 0;
1772 return 0;
1775 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
1777 if (data[0] != 0 ||
1778 data[1] != 2) {
1779 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1780 vnc_write_u8(vs, 1); /* Reject version */
1781 vnc_flush(vs);
1782 vnc_client_error(vs);
1783 } else {
1784 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1785 vnc_write_u8(vs, 0); /* Accept version */
1786 vnc_write_u8(vs, 1); /* Number of sub-auths */
1787 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1788 vnc_flush(vs);
1789 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1791 return 0;
1794 static int start_auth_vencrypt(VncState *vs)
1796 /* Send VeNCrypt version 0.2 */
1797 vnc_write_u8(vs, 0);
1798 vnc_write_u8(vs, 2);
1800 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1801 return 0;
1803 #endif /* CONFIG_VNC_TLS */
1805 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1807 /* We only advertise 1 auth scheme at a time, so client
1808 * must pick the one we sent. Verify this */
1809 if (data[0] != vs->auth) { /* Reject auth */
1810 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1811 vnc_write_u32(vs, 1);
1812 if (vs->minor >= 8) {
1813 static const char err[] = "Authentication failed";
1814 vnc_write_u32(vs, sizeof(err));
1815 vnc_write(vs, err, sizeof(err));
1817 vnc_client_error(vs);
1818 } else { /* Accept requested auth */
1819 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1820 switch (vs->auth) {
1821 case VNC_AUTH_NONE:
1822 VNC_DEBUG("Accept auth none\n");
1823 if (vs->minor >= 8) {
1824 vnc_write_u32(vs, 0); /* Accept auth completion */
1825 vnc_flush(vs);
1827 vnc_read_when(vs, protocol_client_init, 1);
1828 break;
1830 case VNC_AUTH_VNC:
1831 VNC_DEBUG("Start VNC auth\n");
1832 return start_auth_vnc(vs);
1834 #if CONFIG_VNC_TLS
1835 case VNC_AUTH_VENCRYPT:
1836 VNC_DEBUG("Accept VeNCrypt auth\n");;
1837 return start_auth_vencrypt(vs);
1838 #endif /* CONFIG_VNC_TLS */
1840 default: /* Should not be possible, but just in case */
1841 VNC_DEBUG("Reject auth %d\n", vs->auth);
1842 vnc_write_u8(vs, 1);
1843 if (vs->minor >= 8) {
1844 static const char err[] = "Authentication failed";
1845 vnc_write_u32(vs, sizeof(err));
1846 vnc_write(vs, err, sizeof(err));
1848 vnc_client_error(vs);
1851 return 0;
1854 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1856 char local[13];
1858 memcpy(local, version, 12);
1859 local[12] = 0;
1861 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1862 VNC_DEBUG("Malformed protocol version %s\n", local);
1863 vnc_client_error(vs);
1864 return 0;
1866 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1867 if (vs->major != 3 ||
1868 (vs->minor != 3 &&
1869 vs->minor != 4 &&
1870 vs->minor != 5 &&
1871 vs->minor != 7 &&
1872 vs->minor != 8)) {
1873 VNC_DEBUG("Unsupported client version\n");
1874 vnc_write_u32(vs, VNC_AUTH_INVALID);
1875 vnc_flush(vs);
1876 vnc_client_error(vs);
1877 return 0;
1879 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1880 * as equivalent to v3.3 by servers
1882 if (vs->minor == 4 || vs->minor == 5)
1883 vs->minor = 3;
1885 if (vs->minor == 3) {
1886 if (vs->auth == VNC_AUTH_NONE) {
1887 VNC_DEBUG("Tell client auth none\n");
1888 vnc_write_u32(vs, vs->auth);
1889 vnc_flush(vs);
1890 vnc_read_when(vs, protocol_client_init, 1);
1891 } else if (vs->auth == VNC_AUTH_VNC) {
1892 VNC_DEBUG("Tell client VNC auth\n");
1893 vnc_write_u32(vs, vs->auth);
1894 vnc_flush(vs);
1895 start_auth_vnc(vs);
1896 } else {
1897 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1898 vnc_write_u32(vs, VNC_AUTH_INVALID);
1899 vnc_flush(vs);
1900 vnc_client_error(vs);
1902 } else {
1903 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1904 vnc_write_u8(vs, 1); /* num auth */
1905 vnc_write_u8(vs, vs->auth);
1906 vnc_read_when(vs, protocol_client_auth, 1);
1907 vnc_flush(vs);
1910 return 0;
1913 static void vnc_listen_read(void *opaque)
1915 VncState *vs = opaque;
1916 struct sockaddr_in addr;
1917 socklen_t addrlen = sizeof(addr);
1919 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1920 if (vs->csock != -1) {
1921 VNC_DEBUG("New client on socket %d\n", vs->csock);
1922 socket_set_nonblock(vs->csock);
1923 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
1924 vnc_write(vs, "RFB 003.008\n", 12);
1925 vnc_flush(vs);
1926 vnc_read_when(vs, protocol_version, 12);
1927 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1928 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1929 vs->has_resize = 0;
1930 vs->has_hextile = 0;
1931 vs->ds->dpy_copy = NULL;
1935 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1937 void vnc_display_init(DisplayState *ds)
1939 VncState *vs;
1941 vs = qemu_mallocz(sizeof(VncState));
1942 if (!vs)
1943 exit(1);
1945 ds->opaque = vs;
1946 vnc_state = vs;
1947 vs->display = NULL;
1948 vs->password = NULL;
1950 vs->lsock = -1;
1951 vs->csock = -1;
1952 vs->depth = 4;
1953 vs->last_x = -1;
1954 vs->last_y = -1;
1956 vs->ds = ds;
1958 if (!keyboard_layout)
1959 keyboard_layout = "en-us";
1961 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1962 if (!vs->kbd_layout)
1963 exit(1);
1965 vs->ds->data = NULL;
1966 vs->ds->dpy_update = vnc_dpy_update;
1967 vs->ds->dpy_resize = vnc_dpy_resize;
1968 vs->ds->dpy_refresh = vnc_dpy_refresh;
1970 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1972 vnc_dpy_resize(vs->ds, 640, 400);
1975 #if CONFIG_VNC_TLS
1976 static int vnc_set_x509_credential(VncState *vs,
1977 const char *certdir,
1978 const char *filename,
1979 char **cred,
1980 int ignoreMissing)
1982 struct stat sb;
1984 if (*cred) {
1985 qemu_free(*cred);
1986 *cred = NULL;
1989 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
1990 return -1;
1992 strcpy(*cred, certdir);
1993 strcat(*cred, "/");
1994 strcat(*cred, filename);
1996 VNC_DEBUG("Check %s\n", *cred);
1997 if (stat(*cred, &sb) < 0) {
1998 qemu_free(*cred);
1999 *cred = NULL;
2000 if (ignoreMissing && errno == ENOENT)
2001 return 0;
2002 return -1;
2005 return 0;
2008 static int vnc_set_x509_credential_dir(VncState *vs,
2009 const char *certdir)
2011 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2012 goto cleanup;
2013 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2014 goto cleanup;
2015 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2016 goto cleanup;
2017 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2018 goto cleanup;
2020 return 0;
2022 cleanup:
2023 qemu_free(vs->x509cacert);
2024 qemu_free(vs->x509cacrl);
2025 qemu_free(vs->x509cert);
2026 qemu_free(vs->x509key);
2027 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2028 return -1;
2030 #endif /* CONFIG_VNC_TLS */
2032 void vnc_display_close(DisplayState *ds)
2034 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2036 if (vs->display) {
2037 qemu_free(vs->display);
2038 vs->display = NULL;
2040 if (vs->lsock != -1) {
2041 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2042 close(vs->lsock);
2043 vs->lsock = -1;
2045 if (vs->csock != -1) {
2046 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2047 closesocket(vs->csock);
2048 vs->csock = -1;
2049 buffer_reset(&vs->input);
2050 buffer_reset(&vs->output);
2051 vs->need_update = 0;
2052 #if CONFIG_VNC_TLS
2053 if (vs->tls_session) {
2054 gnutls_deinit(vs->tls_session);
2055 vs->tls_session = NULL;
2057 vs->wiremode = VNC_WIREMODE_CLEAR;
2058 #endif /* CONFIG_VNC_TLS */
2060 vs->auth = VNC_AUTH_INVALID;
2061 #if CONFIG_VNC_TLS
2062 vs->subauth = VNC_AUTH_INVALID;
2063 vs->x509verify = 0;
2064 #endif
2067 int vnc_display_password(DisplayState *ds, const char *password)
2069 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2071 if (vs->password) {
2072 qemu_free(vs->password);
2073 vs->password = NULL;
2075 if (password && password[0]) {
2076 if (!(vs->password = qemu_strdup(password)))
2077 return -1;
2080 return 0;
2083 int vnc_display_open(DisplayState *ds, const char *display)
2085 struct sockaddr *addr;
2086 struct sockaddr_in iaddr;
2087 #ifndef _WIN32
2088 struct sockaddr_un uaddr;
2089 #endif
2090 int reuse_addr, ret;
2091 socklen_t addrlen;
2092 const char *p;
2093 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2094 const char *options;
2095 int password = 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 #if CONFIG_VNC_TLS
2113 } else if (strncmp(options, "tls", 3) == 0) {
2114 tls = 1; /* Require TLS */
2115 } else if (strncmp(options, "x509", 4) == 0) {
2116 char *start, *end;
2117 x509 = 1; /* Require x509 certificates */
2118 if (strncmp(options, "x509verify", 10) == 0)
2119 vs->x509verify = 1; /* ...and verify client certs */
2121 /* Now check for 'x509=/some/path' postfix
2122 * and use that to setup x509 certificate/key paths */
2123 start = strchr(options, '=');
2124 end = strchr(options, ',');
2125 if (start && (!end || (start < end))) {
2126 int len = end ? end-(start+1) : strlen(start+1);
2127 char *path = qemu_malloc(len+1);
2128 strncpy(path, start+1, len);
2129 path[len] = '\0';
2130 VNC_DEBUG("Trying certificate path '%s'\n", path);
2131 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2132 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2133 qemu_free(path);
2134 qemu_free(vs->display);
2135 vs->display = NULL;
2136 return -1;
2138 qemu_free(path);
2139 } else {
2140 fprintf(stderr, "No certificate path provided\n");
2141 qemu_free(vs->display);
2142 vs->display = NULL;
2143 return -1;
2145 #endif
2149 if (password) {
2150 #if CONFIG_VNC_TLS
2151 if (tls) {
2152 vs->auth = VNC_AUTH_VENCRYPT;
2153 if (x509) {
2154 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2155 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2156 } else {
2157 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2158 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2160 } else {
2161 #endif
2162 VNC_DEBUG("Initializing VNC server with password auth\n");
2163 vs->auth = VNC_AUTH_VNC;
2164 #if CONFIG_VNC_TLS
2165 vs->subauth = VNC_AUTH_INVALID;
2167 #endif
2168 } else {
2169 #if CONFIG_VNC_TLS
2170 if (tls) {
2171 vs->auth = VNC_AUTH_VENCRYPT;
2172 if (x509) {
2173 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2174 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2175 } else {
2176 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2177 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2179 } else {
2180 #endif
2181 VNC_DEBUG("Initializing VNC server with no auth\n");
2182 vs->auth = VNC_AUTH_NONE;
2183 #if CONFIG_VNC_TLS
2184 vs->subauth = VNC_AUTH_INVALID;
2186 #endif
2188 #ifndef _WIN32
2189 if (strstart(display, "unix:", &p)) {
2190 addr = (struct sockaddr *)&uaddr;
2191 addrlen = sizeof(uaddr);
2193 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2194 if (vs->lsock == -1) {
2195 fprintf(stderr, "Could not create socket\n");
2196 free(vs->display);
2197 vs->display = NULL;
2198 return -1;
2201 uaddr.sun_family = AF_UNIX;
2202 memset(uaddr.sun_path, 0, 108);
2203 snprintf(uaddr.sun_path, 108, "%s", p);
2205 unlink(uaddr.sun_path);
2206 } else
2207 #endif
2209 addr = (struct sockaddr *)&iaddr;
2210 addrlen = sizeof(iaddr);
2212 if (parse_host_port(&iaddr, display) < 0) {
2213 fprintf(stderr, "Could not parse VNC address\n");
2214 free(vs->display);
2215 vs->display = NULL;
2216 return -1;
2219 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
2221 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2222 if (vs->lsock == -1) {
2223 fprintf(stderr, "Could not create socket\n");
2224 free(vs->display);
2225 vs->display = NULL;
2226 return -1;
2229 reuse_addr = 1;
2230 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2231 (const char *)&reuse_addr, sizeof(reuse_addr));
2232 if (ret == -1) {
2233 fprintf(stderr, "setsockopt() failed\n");
2234 close(vs->lsock);
2235 vs->lsock = -1;
2236 free(vs->display);
2237 vs->display = NULL;
2238 return -1;
2242 if (bind(vs->lsock, addr, addrlen) == -1) {
2243 fprintf(stderr, "bind() failed\n");
2244 close(vs->lsock);
2245 vs->lsock = -1;
2246 free(vs->display);
2247 vs->display = NULL;
2248 return -1;
2251 if (listen(vs->lsock, 1) == -1) {
2252 fprintf(stderr, "listen() failed\n");
2253 close(vs->lsock);
2254 vs->lsock = -1;
2255 free(vs->display);
2256 vs->display = NULL;
2257 return -1;
2260 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);