Display TCGCond name in tcg dumper (original patch by Tristan Gingold)
[qemu/mini2440.git] / vnc.c
blob3c029f5f1c3046bfe435c60ecb52fccdc7182f85
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 #ifdef CONFIG_VNC_TLS
39 #include <gnutls/gnutls.h>
40 #include <gnutls/x509.h>
41 #endif /* CONFIG_VNC_TLS */
43 // #define _VNC_DEBUG 1
45 #ifdef _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 #ifdef 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 #define X509_CA_CERT_FILE "ca-cert.pem"
113 #define X509_CA_CRL_FILE "ca-crl.pem"
114 #define X509_SERVER_KEY_FILE "server-key.pem"
115 #define X509_SERVER_CERT_FILE "server-cert.pem"
117 #endif /* CONFIG_VNC_TLS */
119 struct VncState
121 QEMUTimer *timer;
122 int lsock;
123 int csock;
124 DisplayState *ds;
125 int need_update;
126 int width;
127 int height;
128 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
129 char *old_data;
130 int depth; /* internal VNC frame buffer byte per pixel */
131 int has_resize;
132 int has_hextile;
133 int has_pointer_type_change;
134 int absolute;
135 int last_x;
136 int last_y;
138 int major;
139 int minor;
141 char *display;
142 char *password;
143 int auth;
144 #ifdef CONFIG_VNC_TLS
145 int subauth;
146 int x509verify;
148 char *x509cacert;
149 char *x509cacrl;
150 char *x509cert;
151 char *x509key;
152 #endif
153 char challenge[VNC_AUTH_CHALLENGE_SIZE];
155 #ifdef CONFIG_VNC_TLS
156 int wiremode;
157 gnutls_session_t tls_session;
158 #endif
160 Buffer output;
161 Buffer input;
162 kbd_layout_t *kbd_layout;
163 /* current output mode information */
164 VncWritePixels *write_pixels;
165 VncSendHextileTile *send_hextile_tile;
166 int pix_bpp, pix_big_endian;
167 int red_shift, red_max, red_shift1;
168 int green_shift, green_max, green_shift1;
169 int blue_shift, blue_max, blue_shift1;
171 VncReadEvent *read_handler;
172 size_t read_handler_expect;
173 /* input */
174 uint8_t modifiers_state[256];
177 static VncState *vnc_state; /* needed for info vnc */
179 void do_info_vnc(void)
181 if (vnc_state == NULL)
182 term_printf("VNC server disabled\n");
183 else {
184 term_printf("VNC server active on: ");
185 term_print_filename(vnc_state->display);
186 term_printf("\n");
188 if (vnc_state->csock == -1)
189 term_printf("No client connected\n");
190 else
191 term_printf("Client connected\n");
195 /* TODO
196 1) Get the queue working for IO.
197 2) there is some weirdness when using the -S option (the screen is grey
198 and not totally invalidated
199 3) resolutions > 1024
202 static void vnc_write(VncState *vs, const void *data, size_t len);
203 static void vnc_write_u32(VncState *vs, uint32_t value);
204 static void vnc_write_s32(VncState *vs, int32_t value);
205 static void vnc_write_u16(VncState *vs, uint16_t value);
206 static void vnc_write_u8(VncState *vs, uint8_t value);
207 static void vnc_flush(VncState *vs);
208 static void vnc_update_client(void *opaque);
209 static void vnc_client_read(void *opaque);
211 static inline void vnc_set_bit(uint32_t *d, int k)
213 d[k >> 5] |= 1 << (k & 0x1f);
216 static inline void vnc_clear_bit(uint32_t *d, int k)
218 d[k >> 5] &= ~(1 << (k & 0x1f));
221 static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
223 int j;
225 j = 0;
226 while (n >= 32) {
227 d[j++] = -1;
228 n -= 32;
230 if (n > 0)
231 d[j++] = (1 << n) - 1;
232 while (j < nb_words)
233 d[j++] = 0;
236 static inline int vnc_get_bit(const uint32_t *d, int k)
238 return (d[k >> 5] >> (k & 0x1f)) & 1;
241 static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
242 int nb_words)
244 int i;
245 for(i = 0; i < nb_words; i++) {
246 if ((d1[i] & d2[i]) != 0)
247 return 1;
249 return 0;
252 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
254 VncState *vs = ds->opaque;
255 int i;
257 h += y;
259 /* round x down to ensure the loop only spans one 16-pixel block per,
260 iteration. otherwise, if (x % 16) != 0, the last iteration may span
261 two 16-pixel blocks but we only mark the first as dirty
263 w += (x % 16);
264 x -= (x % 16);
266 x = MIN(x, vs->width);
267 y = MIN(y, vs->height);
268 w = MIN(x + w, vs->width) - x;
269 h = MIN(h, vs->height);
271 for (; y < h; y++)
272 for (i = 0; i < w; i += 16)
273 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
276 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
277 int32_t encoding)
279 vnc_write_u16(vs, x);
280 vnc_write_u16(vs, y);
281 vnc_write_u16(vs, w);
282 vnc_write_u16(vs, h);
284 vnc_write_s32(vs, encoding);
287 static void vnc_dpy_resize(DisplayState *ds, int w, int h)
289 int size_changed;
290 VncState *vs = ds->opaque;
292 ds->data = qemu_realloc(ds->data, w * h * vs->depth);
293 vs->old_data = qemu_realloc(vs->old_data, w * h * vs->depth);
295 if (ds->data == NULL || vs->old_data == NULL) {
296 fprintf(stderr, "vnc: memory allocation failed\n");
297 exit(1);
300 if (ds->depth != vs->depth * 8) {
301 ds->depth = vs->depth * 8;
302 console_color_init(ds);
304 size_changed = ds->width != w || ds->height != h;
305 ds->width = w;
306 ds->height = h;
307 ds->linesize = w * vs->depth;
308 if (size_changed) {
309 vs->width = ds->width;
310 vs->height = ds->height;
311 if (vs->csock != -1 && vs->has_resize) {
312 vnc_write_u8(vs, 0); /* msg id */
313 vnc_write_u8(vs, 0);
314 vnc_write_u16(vs, 1); /* number of rects */
315 vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
316 vnc_flush(vs);
320 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
321 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
324 /* fastest code */
325 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
327 vnc_write(vs, pixels, size);
330 /* slowest but generic code. */
331 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
333 unsigned int r, g, b;
335 r = (v >> vs->red_shift1) & vs->red_max;
336 g = (v >> vs->green_shift1) & vs->green_max;
337 b = (v >> vs->blue_shift1) & vs->blue_max;
338 v = (r << vs->red_shift) |
339 (g << vs->green_shift) |
340 (b << vs->blue_shift);
341 switch(vs->pix_bpp) {
342 case 1:
343 buf[0] = v;
344 break;
345 case 2:
346 if (vs->pix_big_endian) {
347 buf[0] = v >> 8;
348 buf[1] = v;
349 } else {
350 buf[1] = v >> 8;
351 buf[0] = v;
353 break;
354 default:
355 case 4:
356 if (vs->pix_big_endian) {
357 buf[0] = v >> 24;
358 buf[1] = v >> 16;
359 buf[2] = v >> 8;
360 buf[3] = v;
361 } else {
362 buf[3] = v >> 24;
363 buf[2] = v >> 16;
364 buf[1] = v >> 8;
365 buf[0] = v;
367 break;
371 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
373 uint32_t *pixels = pixels1;
374 uint8_t buf[4];
375 int n, i;
377 n = size >> 2;
378 for(i = 0; i < n; i++) {
379 vnc_convert_pixel(vs, buf, pixels[i]);
380 vnc_write(vs, buf, vs->pix_bpp);
384 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
386 int i;
387 uint8_t *row;
389 vnc_framebuffer_update(vs, x, y, w, h, 0);
391 row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
392 for (i = 0; i < h; i++) {
393 vs->write_pixels(vs, row, w * vs->depth);
394 row += vs->ds->linesize;
398 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
400 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
401 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
404 #define BPP 8
405 #include "vnchextile.h"
406 #undef BPP
408 #define BPP 16
409 #include "vnchextile.h"
410 #undef BPP
412 #define BPP 32
413 #include "vnchextile.h"
414 #undef BPP
416 #define GENERIC
417 #define BPP 32
418 #include "vnchextile.h"
419 #undef BPP
420 #undef GENERIC
422 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
424 int i, j;
425 int has_fg, has_bg;
426 uint32_t last_fg32, last_bg32;
428 vnc_framebuffer_update(vs, x, y, w, h, 5);
430 has_fg = has_bg = 0;
431 for (j = y; j < (y + h); j += 16) {
432 for (i = x; i < (x + w); i += 16) {
433 vs->send_hextile_tile(vs, i, j,
434 MIN(16, x + w - i), MIN(16, y + h - j),
435 &last_bg32, &last_fg32, &has_bg, &has_fg);
440 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
442 if (vs->has_hextile)
443 send_framebuffer_update_hextile(vs, x, y, w, h);
444 else
445 send_framebuffer_update_raw(vs, x, y, w, h);
448 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
450 int src, dst;
451 uint8_t *src_row;
452 uint8_t *dst_row;
453 char *old_row;
454 int y = 0;
455 int pitch = ds->linesize;
456 VncState *vs = ds->opaque;
458 vnc_update_client(vs);
460 if (dst_y > src_y) {
461 y = h - 1;
462 pitch = -pitch;
465 src = (ds->linesize * (src_y + y) + vs->depth * src_x);
466 dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
468 src_row = ds->data + src;
469 dst_row = ds->data + dst;
470 old_row = vs->old_data + dst;
472 for (y = 0; y < h; y++) {
473 memmove(old_row, src_row, w * vs->depth);
474 memmove(dst_row, src_row, w * vs->depth);
475 src_row += pitch;
476 dst_row += pitch;
477 old_row += pitch;
480 vnc_write_u8(vs, 0); /* msg id */
481 vnc_write_u8(vs, 0);
482 vnc_write_u16(vs, 1); /* number of rects */
483 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
484 vnc_write_u16(vs, src_x);
485 vnc_write_u16(vs, src_y);
486 vnc_flush(vs);
489 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
491 int h;
493 for (h = 1; h < (vs->height - y); h++) {
494 int tmp_x;
495 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
496 break;
497 for (tmp_x = last_x; tmp_x < x; tmp_x++)
498 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
501 return h;
504 static void vnc_update_client(void *opaque)
506 VncState *vs = opaque;
508 if (vs->need_update && vs->csock != -1) {
509 int y;
510 uint8_t *row;
511 char *old_row;
512 uint32_t width_mask[VNC_DIRTY_WORDS];
513 int n_rectangles;
514 int saved_offset;
515 int has_dirty = 0;
517 vga_hw_update();
519 vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
521 /* Walk through the dirty map and eliminate tiles that
522 really aren't dirty */
523 row = vs->ds->data;
524 old_row = vs->old_data;
526 for (y = 0; y < vs->height; y++) {
527 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
528 int x;
529 uint8_t *ptr;
530 char *old_ptr;
532 ptr = row;
533 old_ptr = (char*)old_row;
535 for (x = 0; x < vs->ds->width; x += 16) {
536 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
537 vnc_clear_bit(vs->dirty_row[y], (x / 16));
538 } else {
539 has_dirty = 1;
540 memcpy(old_ptr, ptr, 16 * vs->depth);
543 ptr += 16 * vs->depth;
544 old_ptr += 16 * vs->depth;
548 row += vs->ds->linesize;
549 old_row += vs->ds->linesize;
552 if (!has_dirty) {
553 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
554 return;
557 /* Count rectangles */
558 n_rectangles = 0;
559 vnc_write_u8(vs, 0); /* msg id */
560 vnc_write_u8(vs, 0);
561 saved_offset = vs->output.offset;
562 vnc_write_u16(vs, 0);
564 for (y = 0; y < vs->height; y++) {
565 int x;
566 int last_x = -1;
567 for (x = 0; x < vs->width / 16; x++) {
568 if (vnc_get_bit(vs->dirty_row[y], x)) {
569 if (last_x == -1) {
570 last_x = x;
572 vnc_clear_bit(vs->dirty_row[y], x);
573 } else {
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++;
579 last_x = -1;
582 if (last_x != -1) {
583 int h = find_dirty_height(vs, y, last_x, x);
584 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
585 n_rectangles++;
588 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
589 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
590 vnc_flush(vs);
594 if (vs->csock != -1) {
595 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
600 static int vnc_listen_poll(void *opaque)
602 VncState *vs = opaque;
603 if (vs->csock == -1)
604 return 1;
605 return 0;
608 static void buffer_reserve(Buffer *buffer, size_t len)
610 if ((buffer->capacity - buffer->offset) < len) {
611 buffer->capacity += (len + 1024);
612 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
613 if (buffer->buffer == NULL) {
614 fprintf(stderr, "vnc: out of memory\n");
615 exit(1);
620 static int buffer_empty(Buffer *buffer)
622 return buffer->offset == 0;
625 static uint8_t *buffer_end(Buffer *buffer)
627 return buffer->buffer + buffer->offset;
630 static void buffer_reset(Buffer *buffer)
632 buffer->offset = 0;
635 static void buffer_append(Buffer *buffer, const void *data, size_t len)
637 memcpy(buffer->buffer + buffer->offset, data, len);
638 buffer->offset += len;
641 static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
643 if (ret == 0 || ret == -1) {
644 if (ret == -1) {
645 switch (last_errno) {
646 case EINTR:
647 case EAGAIN:
648 #ifdef _WIN32
649 case WSAEWOULDBLOCK:
650 #endif
651 return 0;
652 default:
653 break;
657 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
658 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
659 closesocket(vs->csock);
660 vs->csock = -1;
661 vs->ds->idle = 1;
662 buffer_reset(&vs->input);
663 buffer_reset(&vs->output);
664 vs->need_update = 0;
665 #ifdef CONFIG_VNC_TLS
666 if (vs->tls_session) {
667 gnutls_deinit(vs->tls_session);
668 vs->tls_session = NULL;
670 vs->wiremode = VNC_WIREMODE_CLEAR;
671 #endif /* CONFIG_VNC_TLS */
672 return 0;
674 return ret;
677 static void vnc_client_error(VncState *vs)
679 vnc_client_io_error(vs, -1, EINVAL);
682 static void vnc_client_write(void *opaque)
684 long ret;
685 VncState *vs = opaque;
687 #ifdef CONFIG_VNC_TLS
688 if (vs->tls_session) {
689 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
690 if (ret < 0) {
691 if (ret == GNUTLS_E_AGAIN)
692 errno = EAGAIN;
693 else
694 errno = EIO;
695 ret = -1;
697 } else
698 #endif /* CONFIG_VNC_TLS */
699 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
700 ret = vnc_client_io_error(vs, ret, socket_error());
701 if (!ret)
702 return;
704 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
705 vs->output.offset -= ret;
707 if (vs->output.offset == 0) {
708 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
712 static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
714 vs->read_handler = func;
715 vs->read_handler_expect = expecting;
718 static void vnc_client_read(void *opaque)
720 VncState *vs = opaque;
721 long ret;
723 buffer_reserve(&vs->input, 4096);
725 #ifdef CONFIG_VNC_TLS
726 if (vs->tls_session) {
727 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
728 if (ret < 0) {
729 if (ret == GNUTLS_E_AGAIN)
730 errno = EAGAIN;
731 else
732 errno = EIO;
733 ret = -1;
735 } else
736 #endif /* CONFIG_VNC_TLS */
737 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
738 ret = vnc_client_io_error(vs, ret, socket_error());
739 if (!ret)
740 return;
742 vs->input.offset += ret;
744 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
745 size_t len = vs->read_handler_expect;
746 int ret;
748 ret = vs->read_handler(vs, vs->input.buffer, len);
749 if (vs->csock == -1)
750 return;
752 if (!ret) {
753 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
754 vs->input.offset -= len;
755 } else {
756 vs->read_handler_expect = ret;
761 static void vnc_write(VncState *vs, const void *data, size_t len)
763 buffer_reserve(&vs->output, len);
765 if (buffer_empty(&vs->output)) {
766 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
769 buffer_append(&vs->output, data, len);
772 static void vnc_write_s32(VncState *vs, int32_t value)
774 vnc_write_u32(vs, *(uint32_t *)&value);
777 static void vnc_write_u32(VncState *vs, uint32_t value)
779 uint8_t buf[4];
781 buf[0] = (value >> 24) & 0xFF;
782 buf[1] = (value >> 16) & 0xFF;
783 buf[2] = (value >> 8) & 0xFF;
784 buf[3] = value & 0xFF;
786 vnc_write(vs, buf, 4);
789 static void vnc_write_u16(VncState *vs, uint16_t value)
791 uint8_t buf[2];
793 buf[0] = (value >> 8) & 0xFF;
794 buf[1] = value & 0xFF;
796 vnc_write(vs, buf, 2);
799 static void vnc_write_u8(VncState *vs, uint8_t value)
801 vnc_write(vs, (char *)&value, 1);
804 static void vnc_flush(VncState *vs)
806 if (vs->output.offset)
807 vnc_client_write(vs);
810 static uint8_t read_u8(uint8_t *data, size_t offset)
812 return data[offset];
815 static uint16_t read_u16(uint8_t *data, size_t offset)
817 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
820 static int32_t read_s32(uint8_t *data, size_t offset)
822 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
823 (data[offset + 2] << 8) | data[offset + 3]);
826 static uint32_t read_u32(uint8_t *data, size_t offset)
828 return ((data[offset] << 24) | (data[offset + 1] << 16) |
829 (data[offset + 2] << 8) | data[offset + 3]);
832 #ifdef CONFIG_VNC_TLS
833 static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
834 const void *data,
835 size_t len) {
836 struct VncState *vs = (struct VncState *)transport;
837 int ret;
839 retry:
840 ret = send(vs->csock, data, len, 0);
841 if (ret < 0) {
842 if (errno == EINTR)
843 goto retry;
844 return -1;
846 return ret;
850 static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
851 void *data,
852 size_t len) {
853 struct VncState *vs = (struct VncState *)transport;
854 int ret;
856 retry:
857 ret = recv(vs->csock, data, len, 0);
858 if (ret < 0) {
859 if (errno == EINTR)
860 goto retry;
861 return -1;
863 return ret;
865 #endif /* CONFIG_VNC_TLS */
867 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
871 static void check_pointer_type_change(VncState *vs, int absolute)
873 if (vs->has_pointer_type_change && vs->absolute != absolute) {
874 vnc_write_u8(vs, 0);
875 vnc_write_u8(vs, 0);
876 vnc_write_u16(vs, 1);
877 vnc_framebuffer_update(vs, absolute, 0,
878 vs->ds->width, vs->ds->height, -257);
879 vnc_flush(vs);
881 vs->absolute = absolute;
884 static void pointer_event(VncState *vs, int button_mask, int x, int y)
886 int buttons = 0;
887 int dz = 0;
889 if (button_mask & 0x01)
890 buttons |= MOUSE_EVENT_LBUTTON;
891 if (button_mask & 0x02)
892 buttons |= MOUSE_EVENT_MBUTTON;
893 if (button_mask & 0x04)
894 buttons |= MOUSE_EVENT_RBUTTON;
895 if (button_mask & 0x08)
896 dz = -1;
897 if (button_mask & 0x10)
898 dz = 1;
900 if (vs->absolute) {
901 kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
902 y * 0x7FFF / (vs->ds->height - 1),
903 dz, buttons);
904 } else if (vs->has_pointer_type_change) {
905 x -= 0x7FFF;
906 y -= 0x7FFF;
908 kbd_mouse_event(x, y, dz, buttons);
909 } else {
910 if (vs->last_x != -1)
911 kbd_mouse_event(x - vs->last_x,
912 y - vs->last_y,
913 dz, buttons);
914 vs->last_x = x;
915 vs->last_y = y;
918 check_pointer_type_change(vs, kbd_mouse_is_absolute());
921 static void reset_keys(VncState *vs)
923 int i;
924 for(i = 0; i < 256; i++) {
925 if (vs->modifiers_state[i]) {
926 if (i & 0x80)
927 kbd_put_keycode(0xe0);
928 kbd_put_keycode(i | 0x80);
929 vs->modifiers_state[i] = 0;
934 static void press_key(VncState *vs, int keysym)
936 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
937 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
940 static void do_key_event(VncState *vs, int down, int keycode, int sym)
942 /* QEMU console switch */
943 switch(keycode) {
944 case 0x2a: /* Left Shift */
945 case 0x36: /* Right Shift */
946 case 0x1d: /* Left CTRL */
947 case 0x9d: /* Right CTRL */
948 case 0x38: /* Left ALT */
949 case 0xb8: /* Right ALT */
950 if (down)
951 vs->modifiers_state[keycode] = 1;
952 else
953 vs->modifiers_state[keycode] = 0;
954 break;
955 case 0x02 ... 0x0a: /* '1' to '9' keys */
956 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
957 /* Reset the modifiers sent to the current console */
958 reset_keys(vs);
959 console_select(keycode - 0x02);
960 return;
962 break;
963 case 0x3a: /* CapsLock */
964 case 0x45: /* NumLock */
965 if (!down)
966 vs->modifiers_state[keycode] ^= 1;
967 break;
970 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
971 /* If the numlock state needs to change then simulate an additional
972 keypress before sending this one. This will happen if the user
973 toggles numlock away from the VNC window.
975 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
976 if (!vs->modifiers_state[0x45]) {
977 vs->modifiers_state[0x45] = 1;
978 press_key(vs, 0xff7f);
980 } else {
981 if (vs->modifiers_state[0x45]) {
982 vs->modifiers_state[0x45] = 0;
983 press_key(vs, 0xff7f);
988 if (is_graphic_console()) {
989 if (keycode & 0x80)
990 kbd_put_keycode(0xe0);
991 if (down)
992 kbd_put_keycode(keycode & 0x7f);
993 else
994 kbd_put_keycode(keycode | 0x80);
995 } else {
996 /* QEMU console emulation */
997 if (down) {
998 switch (keycode) {
999 case 0x2a: /* Left Shift */
1000 case 0x36: /* Right Shift */
1001 case 0x1d: /* Left CTRL */
1002 case 0x9d: /* Right CTRL */
1003 case 0x38: /* Left ALT */
1004 case 0xb8: /* Right ALT */
1005 break;
1006 case 0xc8:
1007 kbd_put_keysym(QEMU_KEY_UP);
1008 break;
1009 case 0xd0:
1010 kbd_put_keysym(QEMU_KEY_DOWN);
1011 break;
1012 case 0xcb:
1013 kbd_put_keysym(QEMU_KEY_LEFT);
1014 break;
1015 case 0xcd:
1016 kbd_put_keysym(QEMU_KEY_RIGHT);
1017 break;
1018 case 0xd3:
1019 kbd_put_keysym(QEMU_KEY_DELETE);
1020 break;
1021 case 0xc7:
1022 kbd_put_keysym(QEMU_KEY_HOME);
1023 break;
1024 case 0xcf:
1025 kbd_put_keysym(QEMU_KEY_END);
1026 break;
1027 case 0xc9:
1028 kbd_put_keysym(QEMU_KEY_PAGEUP);
1029 break;
1030 case 0xd1:
1031 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1032 break;
1033 default:
1034 kbd_put_keysym(sym);
1035 break;
1041 static void key_event(VncState *vs, int down, uint32_t sym)
1043 int keycode;
1045 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1046 sym = sym - 'A' + 'a';
1048 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
1049 do_key_event(vs, down, keycode, sym);
1052 static void ext_key_event(VncState *vs, int down,
1053 uint32_t sym, uint16_t keycode)
1055 /* if the user specifies a keyboard layout, always use it */
1056 if (keyboard_layout)
1057 key_event(vs, down, sym);
1058 else
1059 do_key_event(vs, down, keycode, sym);
1062 static void framebuffer_update_request(VncState *vs, int incremental,
1063 int x_position, int y_position,
1064 int w, int h)
1066 if (x_position > vs->ds->width)
1067 x_position = vs->ds->width;
1068 if (y_position > vs->ds->height)
1069 y_position = vs->ds->height;
1070 if (x_position + w >= vs->ds->width)
1071 w = vs->ds->width - x_position;
1072 if (y_position + h >= vs->ds->height)
1073 h = vs->ds->height - y_position;
1075 int i;
1076 vs->need_update = 1;
1077 if (!incremental) {
1078 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1080 for (i = 0; i < h; i++) {
1081 vnc_set_bits(vs->dirty_row[y_position + i],
1082 (vs->ds->width / 16), VNC_DIRTY_WORDS);
1083 memset(old_row, 42, vs->ds->width * vs->depth);
1084 old_row += vs->ds->linesize;
1089 static void send_ext_key_event_ack(VncState *vs)
1091 vnc_write_u8(vs, 0);
1092 vnc_write_u8(vs, 0);
1093 vnc_write_u16(vs, 1);
1094 vnc_framebuffer_update(vs, 0, 0, vs->ds->width, vs->ds->height, -258);
1095 vnc_flush(vs);
1098 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1100 int i;
1102 vs->has_hextile = 0;
1103 vs->has_resize = 0;
1104 vs->has_pointer_type_change = 0;
1105 vs->absolute = -1;
1106 vs->ds->dpy_copy = NULL;
1108 for (i = n_encodings - 1; i >= 0; i--) {
1109 switch (encodings[i]) {
1110 case 0: /* Raw */
1111 vs->has_hextile = 0;
1112 break;
1113 case 1: /* CopyRect */
1114 vs->ds->dpy_copy = vnc_copy;
1115 break;
1116 case 5: /* Hextile */
1117 vs->has_hextile = 1;
1118 break;
1119 case -223: /* DesktopResize */
1120 vs->has_resize = 1;
1121 break;
1122 case -257:
1123 vs->has_pointer_type_change = 1;
1124 break;
1125 case -258:
1126 send_ext_key_event_ack(vs);
1127 break;
1128 default:
1129 break;
1133 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1136 static int compute_nbits(unsigned int val)
1138 int n;
1139 n = 0;
1140 while (val != 0) {
1141 n++;
1142 val >>= 1;
1144 return n;
1147 static void set_pixel_format(VncState *vs,
1148 int bits_per_pixel, int depth,
1149 int big_endian_flag, int true_color_flag,
1150 int red_max, int green_max, int blue_max,
1151 int red_shift, int green_shift, int blue_shift)
1153 int host_big_endian_flag;
1155 #ifdef WORDS_BIGENDIAN
1156 host_big_endian_flag = 1;
1157 #else
1158 host_big_endian_flag = 0;
1159 #endif
1160 if (!true_color_flag) {
1161 fail:
1162 vnc_client_error(vs);
1163 return;
1165 if (bits_per_pixel == 32 &&
1166 host_big_endian_flag == big_endian_flag &&
1167 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1168 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1169 vs->depth = 4;
1170 vs->write_pixels = vnc_write_pixels_copy;
1171 vs->send_hextile_tile = send_hextile_tile_32;
1172 } else
1173 if (bits_per_pixel == 16 &&
1174 host_big_endian_flag == big_endian_flag &&
1175 red_max == 31 && green_max == 63 && blue_max == 31 &&
1176 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1177 vs->depth = 2;
1178 vs->write_pixels = vnc_write_pixels_copy;
1179 vs->send_hextile_tile = send_hextile_tile_16;
1180 } else
1181 if (bits_per_pixel == 8 &&
1182 red_max == 7 && green_max == 7 && blue_max == 3 &&
1183 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1184 vs->depth = 1;
1185 vs->write_pixels = vnc_write_pixels_copy;
1186 vs->send_hextile_tile = send_hextile_tile_8;
1187 } else
1189 /* generic and slower case */
1190 if (bits_per_pixel != 8 &&
1191 bits_per_pixel != 16 &&
1192 bits_per_pixel != 32)
1193 goto fail;
1194 vs->depth = 4;
1195 vs->red_shift = red_shift;
1196 vs->red_max = red_max;
1197 vs->red_shift1 = 24 - compute_nbits(red_max);
1198 vs->green_shift = green_shift;
1199 vs->green_max = green_max;
1200 vs->green_shift1 = 16 - compute_nbits(green_max);
1201 vs->blue_shift = blue_shift;
1202 vs->blue_max = blue_max;
1203 vs->blue_shift1 = 8 - compute_nbits(blue_max);
1204 vs->pix_bpp = bits_per_pixel / 8;
1205 vs->pix_big_endian = big_endian_flag;
1206 vs->write_pixels = vnc_write_pixels_generic;
1207 vs->send_hextile_tile = send_hextile_tile_generic;
1210 vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1212 vga_hw_invalidate();
1213 vga_hw_update();
1216 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1218 int i;
1219 uint16_t limit;
1221 switch (data[0]) {
1222 case 0:
1223 if (len == 1)
1224 return 20;
1226 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1227 read_u8(data, 6), read_u8(data, 7),
1228 read_u16(data, 8), read_u16(data, 10),
1229 read_u16(data, 12), read_u8(data, 14),
1230 read_u8(data, 15), read_u8(data, 16));
1231 break;
1232 case 2:
1233 if (len == 1)
1234 return 4;
1236 if (len == 4)
1237 return 4 + (read_u16(data, 2) * 4);
1239 limit = read_u16(data, 2);
1240 for (i = 0; i < limit; i++) {
1241 int32_t val = read_s32(data, 4 + (i * 4));
1242 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1245 set_encodings(vs, (int32_t *)(data + 4), limit);
1246 break;
1247 case 3:
1248 if (len == 1)
1249 return 10;
1251 framebuffer_update_request(vs,
1252 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1253 read_u16(data, 6), read_u16(data, 8));
1254 break;
1255 case 4:
1256 if (len == 1)
1257 return 8;
1259 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1260 break;
1261 case 5:
1262 if (len == 1)
1263 return 6;
1265 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1266 break;
1267 case 6:
1268 if (len == 1)
1269 return 8;
1271 if (len == 8) {
1272 uint32_t dlen = read_u32(data, 4);
1273 if (dlen > 0)
1274 return 8 + dlen;
1277 client_cut_text(vs, read_u32(data, 4), data + 8);
1278 break;
1279 case 255:
1280 if (len == 1)
1281 return 2;
1283 switch (read_u8(data, 1)) {
1284 case 0:
1285 if (len == 2)
1286 return 12;
1288 ext_key_event(vs, read_u16(data, 2),
1289 read_u32(data, 4), read_u32(data, 8));
1290 break;
1291 default:
1292 printf("Msg: %d\n", read_u16(data, 0));
1293 vnc_client_error(vs);
1294 break;
1296 break;
1297 default:
1298 printf("Msg: %d\n", data[0]);
1299 vnc_client_error(vs);
1300 break;
1303 vnc_read_when(vs, protocol_client_msg, 1);
1304 return 0;
1307 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1309 char pad[3] = { 0, 0, 0 };
1310 char buf[1024];
1311 int size;
1313 vs->width = vs->ds->width;
1314 vs->height = vs->ds->height;
1315 vnc_write_u16(vs, vs->ds->width);
1316 vnc_write_u16(vs, vs->ds->height);
1318 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1319 vnc_write_u8(vs, vs->depth * 8); /* depth */
1320 #ifdef WORDS_BIGENDIAN
1321 vnc_write_u8(vs, 1); /* big-endian-flag */
1322 #else
1323 vnc_write_u8(vs, 0); /* big-endian-flag */
1324 #endif
1325 vnc_write_u8(vs, 1); /* true-color-flag */
1326 if (vs->depth == 4) {
1327 vnc_write_u16(vs, 0xFF); /* red-max */
1328 vnc_write_u16(vs, 0xFF); /* green-max */
1329 vnc_write_u16(vs, 0xFF); /* blue-max */
1330 vnc_write_u8(vs, 16); /* red-shift */
1331 vnc_write_u8(vs, 8); /* green-shift */
1332 vnc_write_u8(vs, 0); /* blue-shift */
1333 vs->send_hextile_tile = send_hextile_tile_32;
1334 } else if (vs->depth == 2) {
1335 vnc_write_u16(vs, 31); /* red-max */
1336 vnc_write_u16(vs, 63); /* green-max */
1337 vnc_write_u16(vs, 31); /* blue-max */
1338 vnc_write_u8(vs, 11); /* red-shift */
1339 vnc_write_u8(vs, 5); /* green-shift */
1340 vnc_write_u8(vs, 0); /* blue-shift */
1341 vs->send_hextile_tile = send_hextile_tile_16;
1342 } else if (vs->depth == 1) {
1343 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1344 vnc_write_u16(vs, 7); /* red-max */
1345 vnc_write_u16(vs, 7); /* green-max */
1346 vnc_write_u16(vs, 3); /* blue-max */
1347 vnc_write_u8(vs, 5); /* red-shift */
1348 vnc_write_u8(vs, 2); /* green-shift */
1349 vnc_write_u8(vs, 0); /* blue-shift */
1350 vs->send_hextile_tile = send_hextile_tile_8;
1352 vs->write_pixels = vnc_write_pixels_copy;
1354 vnc_write(vs, pad, 3); /* padding */
1356 if (qemu_name)
1357 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1358 else
1359 size = snprintf(buf, sizeof(buf), "QEMU");
1361 vnc_write_u32(vs, size);
1362 vnc_write(vs, buf, size);
1363 vnc_flush(vs);
1365 vnc_read_when(vs, protocol_client_msg, 1);
1367 return 0;
1370 static void make_challenge(VncState *vs)
1372 int i;
1374 srand(time(NULL)+getpid()+getpid()*987654+rand());
1376 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1377 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1380 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1382 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1383 int i, j, pwlen;
1384 unsigned char key[8];
1386 if (!vs->password || !vs->password[0]) {
1387 VNC_DEBUG("No password configured on server");
1388 vnc_write_u32(vs, 1); /* Reject auth */
1389 if (vs->minor >= 8) {
1390 static const char err[] = "Authentication failed";
1391 vnc_write_u32(vs, sizeof(err));
1392 vnc_write(vs, err, sizeof(err));
1394 vnc_flush(vs);
1395 vnc_client_error(vs);
1396 return 0;
1399 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1401 /* Calculate the expected challenge response */
1402 pwlen = strlen(vs->password);
1403 for (i=0; i<sizeof(key); i++)
1404 key[i] = i<pwlen ? vs->password[i] : 0;
1405 deskey(key, EN0);
1406 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1407 des(response+j, response+j);
1409 /* Compare expected vs actual challenge response */
1410 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1411 VNC_DEBUG("Client challenge reponse did not match\n");
1412 vnc_write_u32(vs, 1); /* Reject auth */
1413 if (vs->minor >= 8) {
1414 static const char err[] = "Authentication failed";
1415 vnc_write_u32(vs, sizeof(err));
1416 vnc_write(vs, err, sizeof(err));
1418 vnc_flush(vs);
1419 vnc_client_error(vs);
1420 } else {
1421 VNC_DEBUG("Accepting VNC challenge response\n");
1422 vnc_write_u32(vs, 0); /* Accept auth */
1423 vnc_flush(vs);
1425 vnc_read_when(vs, protocol_client_init, 1);
1427 return 0;
1430 static int start_auth_vnc(VncState *vs)
1432 make_challenge(vs);
1433 /* Send client a 'random' challenge */
1434 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1435 vnc_flush(vs);
1437 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1438 return 0;
1442 #ifdef CONFIG_VNC_TLS
1443 #define DH_BITS 1024
1444 static gnutls_dh_params_t dh_params;
1446 static int vnc_tls_initialize(void)
1448 static int tlsinitialized = 0;
1450 if (tlsinitialized)
1451 return 1;
1453 if (gnutls_global_init () < 0)
1454 return 0;
1456 /* XXX ought to re-generate diffie-hellmen params periodically */
1457 if (gnutls_dh_params_init (&dh_params) < 0)
1458 return 0;
1459 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1460 return 0;
1462 #if _VNC_DEBUG == 2
1463 gnutls_global_set_log_level(10);
1464 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1465 #endif
1467 tlsinitialized = 1;
1469 return 1;
1472 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1474 gnutls_anon_server_credentials anon_cred;
1475 int ret;
1477 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1478 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1479 return NULL;
1482 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1484 return anon_cred;
1488 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1490 gnutls_certificate_credentials_t x509_cred;
1491 int ret;
1493 if (!vs->x509cacert) {
1494 VNC_DEBUG("No CA x509 certificate specified\n");
1495 return NULL;
1497 if (!vs->x509cert) {
1498 VNC_DEBUG("No server x509 certificate specified\n");
1499 return NULL;
1501 if (!vs->x509key) {
1502 VNC_DEBUG("No server private key specified\n");
1503 return NULL;
1506 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1507 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1508 return NULL;
1510 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1511 vs->x509cacert,
1512 GNUTLS_X509_FMT_PEM)) < 0) {
1513 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1514 gnutls_certificate_free_credentials(x509_cred);
1515 return NULL;
1518 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1519 vs->x509cert,
1520 vs->x509key,
1521 GNUTLS_X509_FMT_PEM)) < 0) {
1522 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1523 gnutls_certificate_free_credentials(x509_cred);
1524 return NULL;
1527 if (vs->x509cacrl) {
1528 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1529 vs->x509cacrl,
1530 GNUTLS_X509_FMT_PEM)) < 0) {
1531 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1532 gnutls_certificate_free_credentials(x509_cred);
1533 return NULL;
1537 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1539 return x509_cred;
1542 static int vnc_validate_certificate(struct VncState *vs)
1544 int ret;
1545 unsigned int status;
1546 const gnutls_datum_t *certs;
1547 unsigned int nCerts, i;
1548 time_t now;
1550 VNC_DEBUG("Validating client certificate\n");
1551 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1552 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1553 return -1;
1556 if ((now = time(NULL)) == ((time_t)-1)) {
1557 return -1;
1560 if (status != 0) {
1561 if (status & GNUTLS_CERT_INVALID)
1562 VNC_DEBUG("The certificate is not trusted.\n");
1564 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1565 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1567 if (status & GNUTLS_CERT_REVOKED)
1568 VNC_DEBUG("The certificate has been revoked.\n");
1570 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1571 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1573 return -1;
1574 } else {
1575 VNC_DEBUG("Certificate is valid!\n");
1578 /* Only support x509 for now */
1579 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1580 return -1;
1582 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1583 return -1;
1585 for (i = 0 ; i < nCerts ; i++) {
1586 gnutls_x509_crt_t cert;
1587 VNC_DEBUG ("Checking certificate chain %d\n", i);
1588 if (gnutls_x509_crt_init (&cert) < 0)
1589 return -1;
1591 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1592 gnutls_x509_crt_deinit (cert);
1593 return -1;
1596 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1597 VNC_DEBUG("The certificate has expired\n");
1598 gnutls_x509_crt_deinit (cert);
1599 return -1;
1602 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1603 VNC_DEBUG("The certificate is not yet activated\n");
1604 gnutls_x509_crt_deinit (cert);
1605 return -1;
1608 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1609 VNC_DEBUG("The certificate is not yet activated\n");
1610 gnutls_x509_crt_deinit (cert);
1611 return -1;
1614 gnutls_x509_crt_deinit (cert);
1617 return 0;
1621 static int start_auth_vencrypt_subauth(VncState *vs)
1623 switch (vs->subauth) {
1624 case VNC_AUTH_VENCRYPT_TLSNONE:
1625 case VNC_AUTH_VENCRYPT_X509NONE:
1626 VNC_DEBUG("Accept TLS auth none\n");
1627 vnc_write_u32(vs, 0); /* Accept auth completion */
1628 vnc_read_when(vs, protocol_client_init, 1);
1629 break;
1631 case VNC_AUTH_VENCRYPT_TLSVNC:
1632 case VNC_AUTH_VENCRYPT_X509VNC:
1633 VNC_DEBUG("Start TLS auth VNC\n");
1634 return start_auth_vnc(vs);
1636 default: /* Should not be possible, but just in case */
1637 VNC_DEBUG("Reject auth %d\n", vs->auth);
1638 vnc_write_u8(vs, 1);
1639 if (vs->minor >= 8) {
1640 static const char err[] = "Unsupported authentication type";
1641 vnc_write_u32(vs, sizeof(err));
1642 vnc_write(vs, err, sizeof(err));
1644 vnc_client_error(vs);
1647 return 0;
1650 static void vnc_handshake_io(void *opaque);
1652 static int vnc_continue_handshake(struct VncState *vs) {
1653 int ret;
1655 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1656 if (!gnutls_error_is_fatal(ret)) {
1657 VNC_DEBUG("Handshake interrupted (blocking)\n");
1658 if (!gnutls_record_get_direction(vs->tls_session))
1659 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1660 else
1661 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1662 return 0;
1664 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1665 vnc_client_error(vs);
1666 return -1;
1669 if (vs->x509verify) {
1670 if (vnc_validate_certificate(vs) < 0) {
1671 VNC_DEBUG("Client verification failed\n");
1672 vnc_client_error(vs);
1673 return -1;
1674 } else {
1675 VNC_DEBUG("Client verification passed\n");
1679 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1680 vs->wiremode = VNC_WIREMODE_TLS;
1681 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1683 return start_auth_vencrypt_subauth(vs);
1686 static void vnc_handshake_io(void *opaque) {
1687 struct VncState *vs = (struct VncState *)opaque;
1689 VNC_DEBUG("Handshake IO continue\n");
1690 vnc_continue_handshake(vs);
1693 #define NEED_X509_AUTH(vs) \
1694 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1695 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1696 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1699 static int vnc_start_tls(struct VncState *vs) {
1700 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1701 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1702 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1703 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1705 VNC_DEBUG("Do TLS setup\n");
1706 if (vnc_tls_initialize() < 0) {
1707 VNC_DEBUG("Failed to init TLS\n");
1708 vnc_client_error(vs);
1709 return -1;
1711 if (vs->tls_session == NULL) {
1712 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1713 vnc_client_error(vs);
1714 return -1;
1717 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1718 gnutls_deinit(vs->tls_session);
1719 vs->tls_session = NULL;
1720 vnc_client_error(vs);
1721 return -1;
1724 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1725 gnutls_deinit(vs->tls_session);
1726 vs->tls_session = NULL;
1727 vnc_client_error(vs);
1728 return -1;
1731 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1732 gnutls_deinit(vs->tls_session);
1733 vs->tls_session = NULL;
1734 vnc_client_error(vs);
1735 return -1;
1738 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1739 gnutls_deinit(vs->tls_session);
1740 vs->tls_session = NULL;
1741 vnc_client_error(vs);
1742 return -1;
1745 if (NEED_X509_AUTH(vs)) {
1746 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1747 if (!x509_cred) {
1748 gnutls_deinit(vs->tls_session);
1749 vs->tls_session = NULL;
1750 vnc_client_error(vs);
1751 return -1;
1753 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1754 gnutls_deinit(vs->tls_session);
1755 vs->tls_session = NULL;
1756 gnutls_certificate_free_credentials(x509_cred);
1757 vnc_client_error(vs);
1758 return -1;
1760 if (vs->x509verify) {
1761 VNC_DEBUG("Requesting a client certificate\n");
1762 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1765 } else {
1766 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1767 if (!anon_cred) {
1768 gnutls_deinit(vs->tls_session);
1769 vs->tls_session = NULL;
1770 vnc_client_error(vs);
1771 return -1;
1773 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1774 gnutls_deinit(vs->tls_session);
1775 vs->tls_session = NULL;
1776 gnutls_anon_free_server_credentials(anon_cred);
1777 vnc_client_error(vs);
1778 return -1;
1782 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1783 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1784 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1787 VNC_DEBUG("Start TLS handshake process\n");
1788 return vnc_continue_handshake(vs);
1791 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
1793 int auth = read_u32(data, 0);
1795 if (auth != vs->subauth) {
1796 VNC_DEBUG("Rejecting auth %d\n", auth);
1797 vnc_write_u8(vs, 0); /* Reject auth */
1798 vnc_flush(vs);
1799 vnc_client_error(vs);
1800 } else {
1801 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1802 vnc_write_u8(vs, 1); /* Accept auth */
1803 vnc_flush(vs);
1805 if (vnc_start_tls(vs) < 0) {
1806 VNC_DEBUG("Failed to complete TLS\n");
1807 return 0;
1810 if (vs->wiremode == VNC_WIREMODE_TLS) {
1811 VNC_DEBUG("Starting VeNCrypt subauth\n");
1812 return start_auth_vencrypt_subauth(vs);
1813 } else {
1814 VNC_DEBUG("TLS handshake blocked\n");
1815 return 0;
1818 return 0;
1821 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
1823 if (data[0] != 0 ||
1824 data[1] != 2) {
1825 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1826 vnc_write_u8(vs, 1); /* Reject version */
1827 vnc_flush(vs);
1828 vnc_client_error(vs);
1829 } else {
1830 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1831 vnc_write_u8(vs, 0); /* Accept version */
1832 vnc_write_u8(vs, 1); /* Number of sub-auths */
1833 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1834 vnc_flush(vs);
1835 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1837 return 0;
1840 static int start_auth_vencrypt(VncState *vs)
1842 /* Send VeNCrypt version 0.2 */
1843 vnc_write_u8(vs, 0);
1844 vnc_write_u8(vs, 2);
1846 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1847 return 0;
1849 #endif /* CONFIG_VNC_TLS */
1851 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1853 /* We only advertise 1 auth scheme at a time, so client
1854 * must pick the one we sent. Verify this */
1855 if (data[0] != vs->auth) { /* Reject auth */
1856 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1857 vnc_write_u32(vs, 1);
1858 if (vs->minor >= 8) {
1859 static const char err[] = "Authentication failed";
1860 vnc_write_u32(vs, sizeof(err));
1861 vnc_write(vs, err, sizeof(err));
1863 vnc_client_error(vs);
1864 } else { /* Accept requested auth */
1865 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1866 switch (vs->auth) {
1867 case VNC_AUTH_NONE:
1868 VNC_DEBUG("Accept auth none\n");
1869 if (vs->minor >= 8) {
1870 vnc_write_u32(vs, 0); /* Accept auth completion */
1871 vnc_flush(vs);
1873 vnc_read_when(vs, protocol_client_init, 1);
1874 break;
1876 case VNC_AUTH_VNC:
1877 VNC_DEBUG("Start VNC auth\n");
1878 return start_auth_vnc(vs);
1880 #ifdef CONFIG_VNC_TLS
1881 case VNC_AUTH_VENCRYPT:
1882 VNC_DEBUG("Accept VeNCrypt auth\n");;
1883 return start_auth_vencrypt(vs);
1884 #endif /* CONFIG_VNC_TLS */
1886 default: /* Should not be possible, but just in case */
1887 VNC_DEBUG("Reject auth %d\n", vs->auth);
1888 vnc_write_u8(vs, 1);
1889 if (vs->minor >= 8) {
1890 static const char err[] = "Authentication failed";
1891 vnc_write_u32(vs, sizeof(err));
1892 vnc_write(vs, err, sizeof(err));
1894 vnc_client_error(vs);
1897 return 0;
1900 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1902 char local[13];
1904 memcpy(local, version, 12);
1905 local[12] = 0;
1907 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1908 VNC_DEBUG("Malformed protocol version %s\n", local);
1909 vnc_client_error(vs);
1910 return 0;
1912 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1913 if (vs->major != 3 ||
1914 (vs->minor != 3 &&
1915 vs->minor != 4 &&
1916 vs->minor != 5 &&
1917 vs->minor != 7 &&
1918 vs->minor != 8)) {
1919 VNC_DEBUG("Unsupported client version\n");
1920 vnc_write_u32(vs, VNC_AUTH_INVALID);
1921 vnc_flush(vs);
1922 vnc_client_error(vs);
1923 return 0;
1925 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1926 * as equivalent to v3.3 by servers
1928 if (vs->minor == 4 || vs->minor == 5)
1929 vs->minor = 3;
1931 if (vs->minor == 3) {
1932 if (vs->auth == VNC_AUTH_NONE) {
1933 VNC_DEBUG("Tell client auth none\n");
1934 vnc_write_u32(vs, vs->auth);
1935 vnc_flush(vs);
1936 vnc_read_when(vs, protocol_client_init, 1);
1937 } else if (vs->auth == VNC_AUTH_VNC) {
1938 VNC_DEBUG("Tell client VNC auth\n");
1939 vnc_write_u32(vs, vs->auth);
1940 vnc_flush(vs);
1941 start_auth_vnc(vs);
1942 } else {
1943 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1944 vnc_write_u32(vs, VNC_AUTH_INVALID);
1945 vnc_flush(vs);
1946 vnc_client_error(vs);
1948 } else {
1949 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1950 vnc_write_u8(vs, 1); /* num auth */
1951 vnc_write_u8(vs, vs->auth);
1952 vnc_read_when(vs, protocol_client_auth, 1);
1953 vnc_flush(vs);
1956 return 0;
1959 static void vnc_connect(VncState *vs)
1961 VNC_DEBUG("New client on socket %d\n", vs->csock);
1962 vs->ds->idle = 0;
1963 socket_set_nonblock(vs->csock);
1964 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1965 vnc_write(vs, "RFB 003.008\n", 12);
1966 vnc_flush(vs);
1967 vnc_read_when(vs, protocol_version, 12);
1968 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1969 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1970 vs->has_resize = 0;
1971 vs->has_hextile = 0;
1972 vs->ds->dpy_copy = NULL;
1973 vnc_update_client(vs);
1976 static void vnc_listen_read(void *opaque)
1978 VncState *vs = opaque;
1979 struct sockaddr_in addr;
1980 socklen_t addrlen = sizeof(addr);
1982 /* Catch-up */
1983 vga_hw_update();
1985 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1986 if (vs->csock != -1) {
1987 vnc_connect(vs);
1991 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1993 void vnc_display_init(DisplayState *ds)
1995 VncState *vs;
1997 vs = qemu_mallocz(sizeof(VncState));
1998 if (!vs)
1999 exit(1);
2001 ds->opaque = vs;
2002 ds->idle = 1;
2003 vnc_state = vs;
2004 vs->display = NULL;
2005 vs->password = NULL;
2007 vs->lsock = -1;
2008 vs->csock = -1;
2009 vs->depth = 4;
2010 vs->last_x = -1;
2011 vs->last_y = -1;
2013 vs->ds = ds;
2015 if (keyboard_layout)
2016 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
2017 else
2018 vs->kbd_layout = init_keyboard_layout("en-us");
2020 if (!vs->kbd_layout)
2021 exit(1);
2023 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
2025 vs->ds->data = NULL;
2026 vs->ds->dpy_update = vnc_dpy_update;
2027 vs->ds->dpy_resize = vnc_dpy_resize;
2028 vs->ds->dpy_refresh = NULL;
2030 vnc_dpy_resize(vs->ds, 640, 400);
2033 #ifdef CONFIG_VNC_TLS
2034 static int vnc_set_x509_credential(VncState *vs,
2035 const char *certdir,
2036 const char *filename,
2037 char **cred,
2038 int ignoreMissing)
2040 struct stat sb;
2042 if (*cred) {
2043 qemu_free(*cred);
2044 *cred = NULL;
2047 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
2048 return -1;
2050 strcpy(*cred, certdir);
2051 strcat(*cred, "/");
2052 strcat(*cred, filename);
2054 VNC_DEBUG("Check %s\n", *cred);
2055 if (stat(*cred, &sb) < 0) {
2056 qemu_free(*cred);
2057 *cred = NULL;
2058 if (ignoreMissing && errno == ENOENT)
2059 return 0;
2060 return -1;
2063 return 0;
2066 static int vnc_set_x509_credential_dir(VncState *vs,
2067 const char *certdir)
2069 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2070 goto cleanup;
2071 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2072 goto cleanup;
2073 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2074 goto cleanup;
2075 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2076 goto cleanup;
2078 return 0;
2080 cleanup:
2081 qemu_free(vs->x509cacert);
2082 qemu_free(vs->x509cacrl);
2083 qemu_free(vs->x509cert);
2084 qemu_free(vs->x509key);
2085 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2086 return -1;
2088 #endif /* CONFIG_VNC_TLS */
2090 void vnc_display_close(DisplayState *ds)
2092 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2094 if (vs->display) {
2095 qemu_free(vs->display);
2096 vs->display = NULL;
2098 if (vs->lsock != -1) {
2099 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2100 close(vs->lsock);
2101 vs->lsock = -1;
2103 if (vs->csock != -1) {
2104 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2105 closesocket(vs->csock);
2106 vs->csock = -1;
2107 buffer_reset(&vs->input);
2108 buffer_reset(&vs->output);
2109 vs->need_update = 0;
2110 #ifdef CONFIG_VNC_TLS
2111 if (vs->tls_session) {
2112 gnutls_deinit(vs->tls_session);
2113 vs->tls_session = NULL;
2115 vs->wiremode = VNC_WIREMODE_CLEAR;
2116 #endif /* CONFIG_VNC_TLS */
2118 vs->auth = VNC_AUTH_INVALID;
2119 #ifdef CONFIG_VNC_TLS
2120 vs->subauth = VNC_AUTH_INVALID;
2121 vs->x509verify = 0;
2122 #endif
2125 int vnc_display_password(DisplayState *ds, const char *password)
2127 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2129 if (vs->password) {
2130 qemu_free(vs->password);
2131 vs->password = NULL;
2133 if (password && password[0]) {
2134 if (!(vs->password = qemu_strdup(password)))
2135 return -1;
2138 return 0;
2141 int vnc_display_open(DisplayState *ds, const char *display)
2143 struct sockaddr *addr;
2144 struct sockaddr_in iaddr;
2145 #ifndef _WIN32
2146 struct sockaddr_un uaddr;
2147 const char *p;
2148 #endif
2149 int reuse_addr, ret;
2150 socklen_t addrlen;
2151 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2152 const char *options;
2153 int password = 0;
2154 int reverse = 0;
2155 #ifdef CONFIG_VNC_TLS
2156 int tls = 0, x509 = 0;
2157 #endif
2159 vnc_display_close(ds);
2160 if (strcmp(display, "none") == 0)
2161 return 0;
2163 if (!(vs->display = strdup(display)))
2164 return -1;
2166 options = display;
2167 while ((options = strchr(options, ','))) {
2168 options++;
2169 if (strncmp(options, "password", 8) == 0) {
2170 password = 1; /* Require password auth */
2171 } else if (strncmp(options, "reverse", 7) == 0) {
2172 reverse = 1;
2173 #ifdef CONFIG_VNC_TLS
2174 } else if (strncmp(options, "tls", 3) == 0) {
2175 tls = 1; /* Require TLS */
2176 } else if (strncmp(options, "x509", 4) == 0) {
2177 char *start, *end;
2178 x509 = 1; /* Require x509 certificates */
2179 if (strncmp(options, "x509verify", 10) == 0)
2180 vs->x509verify = 1; /* ...and verify client certs */
2182 /* Now check for 'x509=/some/path' postfix
2183 * and use that to setup x509 certificate/key paths */
2184 start = strchr(options, '=');
2185 end = strchr(options, ',');
2186 if (start && (!end || (start < end))) {
2187 int len = end ? end-(start+1) : strlen(start+1);
2188 char *path = qemu_malloc(len+1);
2189 strncpy(path, start+1, len);
2190 path[len] = '\0';
2191 VNC_DEBUG("Trying certificate path '%s'\n", path);
2192 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2193 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2194 qemu_free(path);
2195 qemu_free(vs->display);
2196 vs->display = NULL;
2197 return -1;
2199 qemu_free(path);
2200 } else {
2201 fprintf(stderr, "No certificate path provided\n");
2202 qemu_free(vs->display);
2203 vs->display = NULL;
2204 return -1;
2206 #endif
2210 if (password) {
2211 #ifdef CONFIG_VNC_TLS
2212 if (tls) {
2213 vs->auth = VNC_AUTH_VENCRYPT;
2214 if (x509) {
2215 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2216 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2217 } else {
2218 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2219 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2221 } else {
2222 #endif
2223 VNC_DEBUG("Initializing VNC server with password auth\n");
2224 vs->auth = VNC_AUTH_VNC;
2225 #ifdef CONFIG_VNC_TLS
2226 vs->subauth = VNC_AUTH_INVALID;
2228 #endif
2229 } else {
2230 #ifdef CONFIG_VNC_TLS
2231 if (tls) {
2232 vs->auth = VNC_AUTH_VENCRYPT;
2233 if (x509) {
2234 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2235 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2236 } else {
2237 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2238 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2240 } else {
2241 #endif
2242 VNC_DEBUG("Initializing VNC server with no auth\n");
2243 vs->auth = VNC_AUTH_NONE;
2244 #ifdef CONFIG_VNC_TLS
2245 vs->subauth = VNC_AUTH_INVALID;
2247 #endif
2249 #ifndef _WIN32
2250 if (strstart(display, "unix:", &p)) {
2251 addr = (struct sockaddr *)&uaddr;
2252 addrlen = sizeof(uaddr);
2254 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2255 if (vs->lsock == -1) {
2256 fprintf(stderr, "Could not create socket\n");
2257 free(vs->display);
2258 vs->display = NULL;
2259 return -1;
2262 uaddr.sun_family = AF_UNIX;
2263 memset(uaddr.sun_path, 0, 108);
2264 snprintf(uaddr.sun_path, 108, "%s", p);
2266 if (!reverse) {
2267 unlink(uaddr.sun_path);
2269 } else
2270 #endif
2272 addr = (struct sockaddr *)&iaddr;
2273 addrlen = sizeof(iaddr);
2275 if (parse_host_port(&iaddr, display) < 0) {
2276 fprintf(stderr, "Could not parse VNC address\n");
2277 free(vs->display);
2278 vs->display = NULL;
2279 return -1;
2282 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900));
2284 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2285 if (vs->lsock == -1) {
2286 fprintf(stderr, "Could not create socket\n");
2287 free(vs->display);
2288 vs->display = NULL;
2289 return -1;
2292 reuse_addr = 1;
2293 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2294 (const char *)&reuse_addr, sizeof(reuse_addr));
2295 if (ret == -1) {
2296 fprintf(stderr, "setsockopt() failed\n");
2297 close(vs->lsock);
2298 vs->lsock = -1;
2299 free(vs->display);
2300 vs->display = NULL;
2301 return -1;
2305 if (reverse) {
2306 if (connect(vs->lsock, addr, addrlen) == -1) {
2307 fprintf(stderr, "Connection to VNC client failed\n");
2308 close(vs->lsock);
2309 vs->lsock = -1;
2310 free(vs->display);
2311 vs->display = NULL;
2312 return -1;
2313 } else {
2314 vs->csock = vs->lsock;
2315 vs->lsock = -1;
2316 vnc_connect(vs);
2317 return 0;
2321 if (bind(vs->lsock, addr, addrlen) == -1) {
2322 fprintf(stderr, "bind() failed\n");
2323 close(vs->lsock);
2324 vs->lsock = -1;
2325 free(vs->display);
2326 vs->display = NULL;
2327 return -1;
2330 if (listen(vs->lsock, 1) == -1) {
2331 fprintf(stderr, "listen() failed\n");
2332 close(vs->lsock);
2333 vs->lsock = -1;
2334 free(vs->display);
2335 vs->display = NULL;
2336 return -1;
2339 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);