Update ARM disassembler.
[qemu/mini2440.git] / vnc.c
blob88cca3b730711aa83e8d0f833e292b15d107ac5f
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 "vl.h"
27 #include "qemu_socket.h"
29 #define VNC_REFRESH_INTERVAL (1000 / 30)
31 #include "vnc_keysym.h"
32 #include "keymaps.c"
33 #include "d3des.h"
35 #if CONFIG_VNC_TLS
36 #include <gnutls/gnutls.h>
37 #include <gnutls/x509.h>
38 #endif /* CONFIG_VNC_TLS */
40 // #define _VNC_DEBUG 1
42 #if _VNC_DEBUG
43 #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
45 #if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
46 /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
47 static void vnc_debug_gnutls_log(int level, const char* str) {
48 VNC_DEBUG("%d %s", level, str);
50 #endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
51 #else
52 #define VNC_DEBUG(fmt, ...) do { } while (0)
53 #endif
56 typedef struct Buffer
58 size_t capacity;
59 size_t offset;
60 char *buffer;
61 } Buffer;
63 typedef struct VncState VncState;
65 typedef int VncReadEvent(VncState *vs, char *data, size_t len);
67 typedef void VncWritePixels(VncState *vs, void *data, int size);
69 typedef void VncSendHextileTile(VncState *vs,
70 int x, int y, int w, int h,
71 uint32_t *last_bg,
72 uint32_t *last_fg,
73 int *has_bg, int *has_fg);
75 #define VNC_MAX_WIDTH 2048
76 #define VNC_MAX_HEIGHT 2048
77 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
79 #define VNC_AUTH_CHALLENGE_SIZE 16
81 enum {
82 VNC_AUTH_INVALID = 0,
83 VNC_AUTH_NONE = 1,
84 VNC_AUTH_VNC = 2,
85 VNC_AUTH_RA2 = 5,
86 VNC_AUTH_RA2NE = 6,
87 VNC_AUTH_TIGHT = 16,
88 VNC_AUTH_ULTRA = 17,
89 VNC_AUTH_TLS = 18,
90 VNC_AUTH_VENCRYPT = 19
93 #if CONFIG_VNC_TLS
94 enum {
95 VNC_WIREMODE_CLEAR,
96 VNC_WIREMODE_TLS,
99 enum {
100 VNC_AUTH_VENCRYPT_PLAIN = 256,
101 VNC_AUTH_VENCRYPT_TLSNONE = 257,
102 VNC_AUTH_VENCRYPT_TLSVNC = 258,
103 VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
104 VNC_AUTH_VENCRYPT_X509NONE = 260,
105 VNC_AUTH_VENCRYPT_X509VNC = 261,
106 VNC_AUTH_VENCRYPT_X509PLAIN = 262,
109 #if CONFIG_VNC_TLS
110 #define X509_CA_CERT_FILE "ca-cert.pem"
111 #define X509_CA_CRL_FILE "ca-crl.pem"
112 #define X509_SERVER_KEY_FILE "server-key.pem"
113 #define X509_SERVER_CERT_FILE "server-cert.pem"
114 #endif
116 #endif /* CONFIG_VNC_TLS */
118 struct VncState
120 QEMUTimer *timer;
121 int lsock;
122 int csock;
123 DisplayState *ds;
124 int need_update;
125 int width;
126 int height;
127 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
128 char *old_data;
129 int depth; /* internal VNC frame buffer byte per pixel */
130 int has_resize;
131 int has_hextile;
132 int has_pointer_type_change;
133 int absolute;
134 int last_x;
135 int last_y;
137 int major;
138 int minor;
140 char *display;
141 char *password;
142 int auth;
143 #if CONFIG_VNC_TLS
144 int subauth;
145 int x509verify;
147 char *x509cacert;
148 char *x509cacrl;
149 char *x509cert;
150 char *x509key;
151 #endif
152 char challenge[VNC_AUTH_CHALLENGE_SIZE];
154 #if CONFIG_VNC_TLS
155 int wiremode;
156 gnutls_session_t tls_session;
157 #endif
159 Buffer output;
160 Buffer input;
161 kbd_layout_t *kbd_layout;
162 /* current output mode information */
163 VncWritePixels *write_pixels;
164 VncSendHextileTile *send_hextile_tile;
165 int pix_bpp, pix_big_endian;
166 int red_shift, red_max, red_shift1;
167 int green_shift, green_max, green_shift1;
168 int blue_shift, blue_max, blue_shift1;
170 VncReadEvent *read_handler;
171 size_t read_handler_expect;
172 /* input */
173 uint8_t modifiers_state[256];
176 static VncState *vnc_state; /* needed for info vnc */
178 void do_info_vnc(void)
180 if (vnc_state == NULL)
181 term_printf("VNC server disabled\n");
182 else {
183 term_printf("VNC server active on: ");
184 term_print_filename(vnc_state->display);
185 term_printf("\n");
187 if (vnc_state->csock == -1)
188 term_printf("No client connected\n");
189 else
190 term_printf("Client connected\n");
194 /* TODO
195 1) Get the queue working for IO.
196 2) there is some weirdness when using the -S option (the screen is grey
197 and not totally invalidated
198 3) resolutions > 1024
201 static void vnc_write(VncState *vs, const void *data, size_t len);
202 static void vnc_write_u32(VncState *vs, uint32_t value);
203 static void vnc_write_s32(VncState *vs, int32_t value);
204 static void vnc_write_u16(VncState *vs, uint16_t value);
205 static void vnc_write_u8(VncState *vs, uint8_t value);
206 static void vnc_flush(VncState *vs);
207 static void vnc_update_client(void *opaque);
208 static void vnc_client_read(void *opaque);
210 static inline void vnc_set_bit(uint32_t *d, int k)
212 d[k >> 5] |= 1 << (k & 0x1f);
215 static inline void vnc_clear_bit(uint32_t *d, int k)
217 d[k >> 5] &= ~(1 << (k & 0x1f));
220 static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
222 int j;
224 j = 0;
225 while (n >= 32) {
226 d[j++] = -1;
227 n -= 32;
229 if (n > 0)
230 d[j++] = (1 << n) - 1;
231 while (j < nb_words)
232 d[j++] = 0;
235 static inline int vnc_get_bit(const uint32_t *d, int k)
237 return (d[k >> 5] >> (k & 0x1f)) & 1;
240 static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
241 int nb_words)
243 int i;
244 for(i = 0; i < nb_words; i++) {
245 if ((d1[i] & d2[i]) != 0)
246 return 1;
248 return 0;
251 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
253 VncState *vs = ds->opaque;
254 int i;
256 h += y;
258 for (; y < h; y++)
259 for (i = 0; i < w; i += 16)
260 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
263 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
264 int32_t encoding)
266 vnc_write_u16(vs, x);
267 vnc_write_u16(vs, y);
268 vnc_write_u16(vs, w);
269 vnc_write_u16(vs, h);
271 vnc_write_s32(vs, encoding);
274 static void vnc_dpy_resize(DisplayState *ds, int w, int h)
276 int size_changed;
277 VncState *vs = ds->opaque;
279 ds->data = realloc(ds->data, w * h * vs->depth);
280 vs->old_data = realloc(vs->old_data, w * h * vs->depth);
282 if (ds->data == NULL || vs->old_data == NULL) {
283 fprintf(stderr, "vnc: memory allocation failed\n");
284 exit(1);
287 if (ds->depth != vs->depth * 8) {
288 ds->depth = vs->depth * 8;
289 console_color_init(ds);
291 size_changed = ds->width != w || ds->height != h;
292 ds->width = w;
293 ds->height = h;
294 ds->linesize = w * vs->depth;
295 if (vs->csock != -1 && vs->has_resize && size_changed) {
296 vnc_write_u8(vs, 0); /* msg id */
297 vnc_write_u8(vs, 0);
298 vnc_write_u16(vs, 1); /* number of rects */
299 vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
300 vnc_flush(vs);
301 vs->width = ds->width;
302 vs->height = ds->height;
306 /* fastest code */
307 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
309 vnc_write(vs, pixels, size);
312 /* slowest but generic code. */
313 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
315 unsigned int r, g, b;
317 r = (v >> vs->red_shift1) & vs->red_max;
318 g = (v >> vs->green_shift1) & vs->green_max;
319 b = (v >> vs->blue_shift1) & vs->blue_max;
320 v = (r << vs->red_shift) |
321 (g << vs->green_shift) |
322 (b << vs->blue_shift);
323 switch(vs->pix_bpp) {
324 case 1:
325 buf[0] = v;
326 break;
327 case 2:
328 if (vs->pix_big_endian) {
329 buf[0] = v >> 8;
330 buf[1] = v;
331 } else {
332 buf[1] = v >> 8;
333 buf[0] = v;
335 break;
336 default:
337 case 4:
338 if (vs->pix_big_endian) {
339 buf[0] = v >> 24;
340 buf[1] = v >> 16;
341 buf[2] = v >> 8;
342 buf[3] = v;
343 } else {
344 buf[3] = v >> 24;
345 buf[2] = v >> 16;
346 buf[1] = v >> 8;
347 buf[0] = v;
349 break;
353 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
355 uint32_t *pixels = pixels1;
356 uint8_t buf[4];
357 int n, i;
359 n = size >> 2;
360 for(i = 0; i < n; i++) {
361 vnc_convert_pixel(vs, buf, pixels[i]);
362 vnc_write(vs, buf, vs->pix_bpp);
366 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
368 int i;
369 char *row;
371 vnc_framebuffer_update(vs, x, y, w, h, 0);
373 row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
374 for (i = 0; i < h; i++) {
375 vs->write_pixels(vs, row, w * vs->depth);
376 row += vs->ds->linesize;
380 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
382 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
383 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
386 #define BPP 8
387 #include "vnchextile.h"
388 #undef BPP
390 #define BPP 16
391 #include "vnchextile.h"
392 #undef BPP
394 #define BPP 32
395 #include "vnchextile.h"
396 #undef BPP
398 #define GENERIC
399 #define BPP 32
400 #include "vnchextile.h"
401 #undef BPP
402 #undef GENERIC
404 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
406 int i, j;
407 int has_fg, has_bg;
408 uint32_t last_fg32, last_bg32;
410 vnc_framebuffer_update(vs, x, y, w, h, 5);
412 has_fg = has_bg = 0;
413 for (j = y; j < (y + h); j += 16) {
414 for (i = x; i < (x + w); i += 16) {
415 vs->send_hextile_tile(vs, i, j,
416 MIN(16, x + w - i), MIN(16, y + h - j),
417 &last_bg32, &last_fg32, &has_bg, &has_fg);
422 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
424 if (vs->has_hextile)
425 send_framebuffer_update_hextile(vs, x, y, w, h);
426 else
427 send_framebuffer_update_raw(vs, x, y, w, h);
430 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
432 int src, dst;
433 char *src_row;
434 char *dst_row;
435 char *old_row;
436 int y = 0;
437 int pitch = ds->linesize;
438 VncState *vs = ds->opaque;
440 vnc_update_client(vs);
442 if (dst_y > src_y) {
443 y = h - 1;
444 pitch = -pitch;
447 src = (ds->linesize * (src_y + y) + vs->depth * src_x);
448 dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
450 src_row = ds->data + src;
451 dst_row = ds->data + dst;
452 old_row = vs->old_data + dst;
454 for (y = 0; y < h; y++) {
455 memmove(old_row, src_row, w * vs->depth);
456 memmove(dst_row, src_row, w * vs->depth);
457 src_row += pitch;
458 dst_row += pitch;
459 old_row += pitch;
462 vnc_write_u8(vs, 0); /* msg id */
463 vnc_write_u8(vs, 0);
464 vnc_write_u16(vs, 1); /* number of rects */
465 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
466 vnc_write_u16(vs, src_x);
467 vnc_write_u16(vs, src_y);
468 vnc_flush(vs);
471 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
473 int h;
475 for (h = 1; h < (vs->height - y); h++) {
476 int tmp_x;
477 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
478 break;
479 for (tmp_x = last_x; tmp_x < x; tmp_x++)
480 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
483 return h;
486 static void vnc_update_client(void *opaque)
488 VncState *vs = opaque;
490 if (vs->need_update && vs->csock != -1) {
491 int y;
492 char *row;
493 char *old_row;
494 uint32_t width_mask[VNC_DIRTY_WORDS];
495 int n_rectangles;
496 int saved_offset;
497 int has_dirty = 0;
499 vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
501 /* Walk through the dirty map and eliminate tiles that
502 really aren't dirty */
503 row = vs->ds->data;
504 old_row = vs->old_data;
506 for (y = 0; y < vs->height; y++) {
507 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
508 int x;
509 char *ptr, *old_ptr;
511 ptr = row;
512 old_ptr = old_row;
514 for (x = 0; x < vs->ds->width; x += 16) {
515 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
516 vnc_clear_bit(vs->dirty_row[y], (x / 16));
517 } else {
518 has_dirty = 1;
519 memcpy(old_ptr, ptr, 16 * vs->depth);
522 ptr += 16 * vs->depth;
523 old_ptr += 16 * vs->depth;
527 row += vs->ds->linesize;
528 old_row += vs->ds->linesize;
531 if (!has_dirty) {
532 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
533 return;
536 /* Count rectangles */
537 n_rectangles = 0;
538 vnc_write_u8(vs, 0); /* msg id */
539 vnc_write_u8(vs, 0);
540 saved_offset = vs->output.offset;
541 vnc_write_u16(vs, 0);
543 for (y = 0; y < vs->height; y++) {
544 int x;
545 int last_x = -1;
546 for (x = 0; x < vs->width / 16; x++) {
547 if (vnc_get_bit(vs->dirty_row[y], x)) {
548 if (last_x == -1) {
549 last_x = x;
551 vnc_clear_bit(vs->dirty_row[y], x);
552 } else {
553 if (last_x != -1) {
554 int h = find_dirty_height(vs, y, last_x, x);
555 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
556 n_rectangles++;
558 last_x = -1;
561 if (last_x != -1) {
562 int h = find_dirty_height(vs, y, last_x, x);
563 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
564 n_rectangles++;
567 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
568 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
569 vnc_flush(vs);
572 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
575 static void vnc_timer_init(VncState *vs)
577 if (vs->timer == NULL) {
578 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
579 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
583 static void vnc_dpy_refresh(DisplayState *ds)
585 VncState *vs = ds->opaque;
586 vnc_timer_init(vs);
587 vga_hw_update();
590 static int vnc_listen_poll(void *opaque)
592 VncState *vs = opaque;
593 if (vs->csock == -1)
594 return 1;
595 return 0;
598 static void buffer_reserve(Buffer *buffer, size_t len)
600 if ((buffer->capacity - buffer->offset) < len) {
601 buffer->capacity += (len + 1024);
602 buffer->buffer = realloc(buffer->buffer, buffer->capacity);
603 if (buffer->buffer == NULL) {
604 fprintf(stderr, "vnc: out of memory\n");
605 exit(1);
610 static int buffer_empty(Buffer *buffer)
612 return buffer->offset == 0;
615 static char *buffer_end(Buffer *buffer)
617 return buffer->buffer + buffer->offset;
620 static void buffer_reset(Buffer *buffer)
622 buffer->offset = 0;
625 static void buffer_append(Buffer *buffer, const void *data, size_t len)
627 memcpy(buffer->buffer + buffer->offset, data, len);
628 buffer->offset += len;
631 static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
633 if (ret == 0 || ret == -1) {
634 if (ret == -1 && (last_errno == EINTR || last_errno == EAGAIN))
635 return 0;
637 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
638 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
639 closesocket(vs->csock);
640 vs->csock = -1;
641 buffer_reset(&vs->input);
642 buffer_reset(&vs->output);
643 vs->need_update = 0;
644 #if CONFIG_VNC_TLS
645 if (vs->tls_session) {
646 gnutls_deinit(vs->tls_session);
647 vs->tls_session = NULL;
649 vs->wiremode = VNC_WIREMODE_CLEAR;
650 #endif /* CONFIG_VNC_TLS */
651 return 0;
653 return ret;
656 static void vnc_client_error(VncState *vs)
658 vnc_client_io_error(vs, -1, EINVAL);
661 static void vnc_client_write(void *opaque)
663 long ret;
664 VncState *vs = opaque;
666 #if CONFIG_VNC_TLS
667 if (vs->tls_session) {
668 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
669 if (ret < 0) {
670 if (ret == GNUTLS_E_AGAIN)
671 errno = EAGAIN;
672 else
673 errno = EIO;
674 ret = -1;
676 } else
677 #endif /* CONFIG_VNC_TLS */
678 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
679 ret = vnc_client_io_error(vs, ret, socket_error());
680 if (!ret)
681 return;
683 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
684 vs->output.offset -= ret;
686 if (vs->output.offset == 0) {
687 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
691 static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
693 vs->read_handler = func;
694 vs->read_handler_expect = expecting;
697 static void vnc_client_read(void *opaque)
699 VncState *vs = opaque;
700 long ret;
702 buffer_reserve(&vs->input, 4096);
704 #if CONFIG_VNC_TLS
705 if (vs->tls_session) {
706 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
707 if (ret < 0) {
708 if (ret == GNUTLS_E_AGAIN)
709 errno = EAGAIN;
710 else
711 errno = EIO;
712 ret = -1;
714 } else
715 #endif /* CONFIG_VNC_TLS */
716 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
717 ret = vnc_client_io_error(vs, ret, socket_error());
718 if (!ret)
719 return;
721 vs->input.offset += ret;
723 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
724 size_t len = vs->read_handler_expect;
725 int ret;
727 ret = vs->read_handler(vs, vs->input.buffer, len);
728 if (vs->csock == -1)
729 return;
731 if (!ret) {
732 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
733 vs->input.offset -= len;
734 } else {
735 vs->read_handler_expect = ret;
740 static void vnc_write(VncState *vs, const void *data, size_t len)
742 buffer_reserve(&vs->output, len);
744 if (buffer_empty(&vs->output)) {
745 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
748 buffer_append(&vs->output, data, len);
751 static void vnc_write_s32(VncState *vs, int32_t value)
753 vnc_write_u32(vs, *(uint32_t *)&value);
756 static void vnc_write_u32(VncState *vs, uint32_t value)
758 uint8_t buf[4];
760 buf[0] = (value >> 24) & 0xFF;
761 buf[1] = (value >> 16) & 0xFF;
762 buf[2] = (value >> 8) & 0xFF;
763 buf[3] = value & 0xFF;
765 vnc_write(vs, buf, 4);
768 static void vnc_write_u16(VncState *vs, uint16_t value)
770 uint8_t buf[2];
772 buf[0] = (value >> 8) & 0xFF;
773 buf[1] = value & 0xFF;
775 vnc_write(vs, buf, 2);
778 static void vnc_write_u8(VncState *vs, uint8_t value)
780 vnc_write(vs, (char *)&value, 1);
783 static void vnc_flush(VncState *vs)
785 if (vs->output.offset)
786 vnc_client_write(vs);
789 static uint8_t read_u8(uint8_t *data, size_t offset)
791 return data[offset];
794 static uint16_t read_u16(uint8_t *data, size_t offset)
796 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
799 static int32_t read_s32(uint8_t *data, size_t offset)
801 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
802 (data[offset + 2] << 8) | data[offset + 3]);
805 static uint32_t read_u32(uint8_t *data, size_t offset)
807 return ((data[offset] << 24) | (data[offset + 1] << 16) |
808 (data[offset + 2] << 8) | data[offset + 3]);
811 #if CONFIG_VNC_TLS
812 ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
813 const void *data,
814 size_t len) {
815 struct VncState *vs = (struct VncState *)transport;
816 int ret;
818 retry:
819 ret = send(vs->csock, data, len, 0);
820 if (ret < 0) {
821 if (errno == EINTR)
822 goto retry;
823 return -1;
825 return ret;
829 ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
830 void *data,
831 size_t len) {
832 struct VncState *vs = (struct VncState *)transport;
833 int ret;
835 retry:
836 ret = recv(vs->csock, data, len, 0);
837 if (ret < 0) {
838 if (errno == EINTR)
839 goto retry;
840 return -1;
842 return ret;
844 #endif /* CONFIG_VNC_TLS */
846 static void client_cut_text(VncState *vs, size_t len, char *text)
850 static void check_pointer_type_change(VncState *vs, int absolute)
852 if (vs->has_pointer_type_change && vs->absolute != absolute) {
853 vnc_write_u8(vs, 0);
854 vnc_write_u8(vs, 0);
855 vnc_write_u16(vs, 1);
856 vnc_framebuffer_update(vs, absolute, 0,
857 vs->ds->width, vs->ds->height, -257);
858 vnc_flush(vs);
860 vs->absolute = absolute;
863 static void pointer_event(VncState *vs, int button_mask, int x, int y)
865 int buttons = 0;
866 int dz = 0;
868 if (button_mask & 0x01)
869 buttons |= MOUSE_EVENT_LBUTTON;
870 if (button_mask & 0x02)
871 buttons |= MOUSE_EVENT_MBUTTON;
872 if (button_mask & 0x04)
873 buttons |= MOUSE_EVENT_RBUTTON;
874 if (button_mask & 0x08)
875 dz = -1;
876 if (button_mask & 0x10)
877 dz = 1;
879 if (vs->absolute) {
880 kbd_mouse_event(x * 0x7FFF / vs->ds->width,
881 y * 0x7FFF / vs->ds->height,
882 dz, buttons);
883 } else if (vs->has_pointer_type_change) {
884 x -= 0x7FFF;
885 y -= 0x7FFF;
887 kbd_mouse_event(x, y, dz, buttons);
888 } else {
889 if (vs->last_x != -1)
890 kbd_mouse_event(x - vs->last_x,
891 y - vs->last_y,
892 dz, buttons);
893 vs->last_x = x;
894 vs->last_y = y;
897 check_pointer_type_change(vs, kbd_mouse_is_absolute());
900 static void reset_keys(VncState *vs)
902 int i;
903 for(i = 0; i < 256; i++) {
904 if (vs->modifiers_state[i]) {
905 if (i & 0x80)
906 kbd_put_keycode(0xe0);
907 kbd_put_keycode(i | 0x80);
908 vs->modifiers_state[i] = 0;
913 static void press_key(VncState *vs, int keysym)
915 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
916 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
919 static void do_key_event(VncState *vs, int down, uint32_t sym)
921 int keycode;
923 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
925 /* QEMU console switch */
926 switch(keycode) {
927 case 0x2a: /* Left Shift */
928 case 0x36: /* Right Shift */
929 case 0x1d: /* Left CTRL */
930 case 0x9d: /* Right CTRL */
931 case 0x38: /* Left ALT */
932 case 0xb8: /* Right ALT */
933 if (down)
934 vs->modifiers_state[keycode] = 1;
935 else
936 vs->modifiers_state[keycode] = 0;
937 break;
938 case 0x02 ... 0x0a: /* '1' to '9' keys */
939 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
940 /* Reset the modifiers sent to the current console */
941 reset_keys(vs);
942 console_select(keycode - 0x02);
943 return;
945 break;
946 case 0x45: /* NumLock */
947 if (!down)
948 vs->modifiers_state[keycode] ^= 1;
949 break;
952 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
953 /* If the numlock state needs to change then simulate an additional
954 keypress before sending this one. This will happen if the user
955 toggles numlock away from the VNC window.
957 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
958 if (!vs->modifiers_state[0x45]) {
959 vs->modifiers_state[0x45] = 1;
960 press_key(vs, 0xff7f);
962 } else {
963 if (vs->modifiers_state[0x45]) {
964 vs->modifiers_state[0x45] = 0;
965 press_key(vs, 0xff7f);
970 if (is_graphic_console()) {
971 if (keycode & 0x80)
972 kbd_put_keycode(0xe0);
973 if (down)
974 kbd_put_keycode(keycode & 0x7f);
975 else
976 kbd_put_keycode(keycode | 0x80);
977 } else {
978 /* QEMU console emulation */
979 if (down) {
980 switch (keycode) {
981 case 0x2a: /* Left Shift */
982 case 0x36: /* Right Shift */
983 case 0x1d: /* Left CTRL */
984 case 0x9d: /* Right CTRL */
985 case 0x38: /* Left ALT */
986 case 0xb8: /* Right ALT */
987 break;
988 case 0xc8:
989 kbd_put_keysym(QEMU_KEY_UP);
990 break;
991 case 0xd0:
992 kbd_put_keysym(QEMU_KEY_DOWN);
993 break;
994 case 0xcb:
995 kbd_put_keysym(QEMU_KEY_LEFT);
996 break;
997 case 0xcd:
998 kbd_put_keysym(QEMU_KEY_RIGHT);
999 break;
1000 case 0xd3:
1001 kbd_put_keysym(QEMU_KEY_DELETE);
1002 break;
1003 case 0xc7:
1004 kbd_put_keysym(QEMU_KEY_HOME);
1005 break;
1006 case 0xcf:
1007 kbd_put_keysym(QEMU_KEY_END);
1008 break;
1009 case 0xc9:
1010 kbd_put_keysym(QEMU_KEY_PAGEUP);
1011 break;
1012 case 0xd1:
1013 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1014 break;
1015 default:
1016 kbd_put_keysym(sym);
1017 break;
1023 static void key_event(VncState *vs, int down, uint32_t sym)
1025 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1026 sym = sym - 'A' + 'a';
1027 do_key_event(vs, down, sym);
1030 static void framebuffer_update_request(VncState *vs, int incremental,
1031 int x_position, int y_position,
1032 int w, int h)
1034 if (x_position > vs->ds->width)
1035 x_position = vs->ds->width;
1036 if (y_position > vs->ds->height)
1037 y_position = vs->ds->height;
1038 if (x_position + w >= vs->ds->width)
1039 w = vs->ds->width - x_position;
1040 if (y_position + h >= vs->ds->height)
1041 h = vs->ds->height - y_position;
1043 int i;
1044 vs->need_update = 1;
1045 if (!incremental) {
1046 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1048 for (i = 0; i < h; i++) {
1049 vnc_set_bits(vs->dirty_row[y_position + i],
1050 (vs->ds->width / 16), VNC_DIRTY_WORDS);
1051 memset(old_row, 42, vs->ds->width * vs->depth);
1052 old_row += vs->ds->linesize;
1057 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1059 int i;
1061 vs->has_hextile = 0;
1062 vs->has_resize = 0;
1063 vs->has_pointer_type_change = 0;
1064 vs->absolute = -1;
1065 vs->ds->dpy_copy = NULL;
1067 for (i = n_encodings - 1; i >= 0; i--) {
1068 switch (encodings[i]) {
1069 case 0: /* Raw */
1070 vs->has_hextile = 0;
1071 break;
1072 case 1: /* CopyRect */
1073 vs->ds->dpy_copy = vnc_copy;
1074 break;
1075 case 5: /* Hextile */
1076 vs->has_hextile = 1;
1077 break;
1078 case -223: /* DesktopResize */
1079 vs->has_resize = 1;
1080 break;
1081 case -257:
1082 vs->has_pointer_type_change = 1;
1083 break;
1084 default:
1085 break;
1089 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1092 static int compute_nbits(unsigned int val)
1094 int n;
1095 n = 0;
1096 while (val != 0) {
1097 n++;
1098 val >>= 1;
1100 return n;
1103 static void set_pixel_format(VncState *vs,
1104 int bits_per_pixel, int depth,
1105 int big_endian_flag, int true_color_flag,
1106 int red_max, int green_max, int blue_max,
1107 int red_shift, int green_shift, int blue_shift)
1109 int host_big_endian_flag;
1111 #ifdef WORDS_BIGENDIAN
1112 host_big_endian_flag = 1;
1113 #else
1114 host_big_endian_flag = 0;
1115 #endif
1116 if (!true_color_flag) {
1117 fail:
1118 vnc_client_error(vs);
1119 return;
1121 if (bits_per_pixel == 32 &&
1122 host_big_endian_flag == big_endian_flag &&
1123 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1124 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1125 vs->depth = 4;
1126 vs->write_pixels = vnc_write_pixels_copy;
1127 vs->send_hextile_tile = send_hextile_tile_32;
1128 } else
1129 if (bits_per_pixel == 16 &&
1130 host_big_endian_flag == big_endian_flag &&
1131 red_max == 31 && green_max == 63 && blue_max == 31 &&
1132 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1133 vs->depth = 2;
1134 vs->write_pixels = vnc_write_pixels_copy;
1135 vs->send_hextile_tile = send_hextile_tile_16;
1136 } else
1137 if (bits_per_pixel == 8 &&
1138 red_max == 7 && green_max == 7 && blue_max == 3 &&
1139 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1140 vs->depth = 1;
1141 vs->write_pixels = vnc_write_pixels_copy;
1142 vs->send_hextile_tile = send_hextile_tile_8;
1143 } else
1145 /* generic and slower case */
1146 if (bits_per_pixel != 8 &&
1147 bits_per_pixel != 16 &&
1148 bits_per_pixel != 32)
1149 goto fail;
1150 vs->depth = 4;
1151 vs->red_shift = red_shift;
1152 vs->red_max = red_max;
1153 vs->red_shift1 = 24 - compute_nbits(red_max);
1154 vs->green_shift = green_shift;
1155 vs->green_max = green_max;
1156 vs->green_shift1 = 16 - compute_nbits(green_max);
1157 vs->blue_shift = blue_shift;
1158 vs->blue_max = blue_max;
1159 vs->blue_shift1 = 8 - compute_nbits(blue_max);
1160 vs->pix_bpp = bits_per_pixel / 8;
1161 vs->pix_big_endian = big_endian_flag;
1162 vs->write_pixels = vnc_write_pixels_generic;
1163 vs->send_hextile_tile = send_hextile_tile_generic;
1166 vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1167 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1168 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
1170 vga_hw_invalidate();
1171 vga_hw_update();
1174 static int protocol_client_msg(VncState *vs, char *data, size_t len)
1176 int i;
1177 uint16_t limit;
1179 switch (data[0]) {
1180 case 0:
1181 if (len == 1)
1182 return 20;
1184 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1185 read_u8(data, 6), read_u8(data, 7),
1186 read_u16(data, 8), read_u16(data, 10),
1187 read_u16(data, 12), read_u8(data, 14),
1188 read_u8(data, 15), read_u8(data, 16));
1189 break;
1190 case 2:
1191 if (len == 1)
1192 return 4;
1194 if (len == 4)
1195 return 4 + (read_u16(data, 2) * 4);
1197 limit = read_u16(data, 2);
1198 for (i = 0; i < limit; i++) {
1199 int32_t val = read_s32(data, 4 + (i * 4));
1200 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1203 set_encodings(vs, (int32_t *)(data + 4), limit);
1204 break;
1205 case 3:
1206 if (len == 1)
1207 return 10;
1209 framebuffer_update_request(vs,
1210 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1211 read_u16(data, 6), read_u16(data, 8));
1212 break;
1213 case 4:
1214 if (len == 1)
1215 return 8;
1217 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1218 break;
1219 case 5:
1220 if (len == 1)
1221 return 6;
1223 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1224 break;
1225 case 6:
1226 if (len == 1)
1227 return 8;
1229 if (len == 8) {
1230 uint32_t dlen = read_u32(data, 4);
1231 if (dlen > 0)
1232 return 8 + dlen;
1235 client_cut_text(vs, read_u32(data, 4), data + 8);
1236 break;
1237 default:
1238 printf("Msg: %d\n", data[0]);
1239 vnc_client_error(vs);
1240 break;
1243 vnc_read_when(vs, protocol_client_msg, 1);
1244 return 0;
1247 static int protocol_client_init(VncState *vs, char *data, size_t len)
1249 char pad[3] = { 0, 0, 0 };
1250 char buf[1024];
1251 int size;
1253 vs->width = vs->ds->width;
1254 vs->height = vs->ds->height;
1255 vnc_write_u16(vs, vs->ds->width);
1256 vnc_write_u16(vs, vs->ds->height);
1258 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1259 vnc_write_u8(vs, vs->depth * 8); /* depth */
1260 #ifdef WORDS_BIGENDIAN
1261 vnc_write_u8(vs, 1); /* big-endian-flag */
1262 #else
1263 vnc_write_u8(vs, 0); /* big-endian-flag */
1264 #endif
1265 vnc_write_u8(vs, 1); /* true-color-flag */
1266 if (vs->depth == 4) {
1267 vnc_write_u16(vs, 0xFF); /* red-max */
1268 vnc_write_u16(vs, 0xFF); /* green-max */
1269 vnc_write_u16(vs, 0xFF); /* blue-max */
1270 vnc_write_u8(vs, 16); /* red-shift */
1271 vnc_write_u8(vs, 8); /* green-shift */
1272 vnc_write_u8(vs, 0); /* blue-shift */
1273 vs->send_hextile_tile = send_hextile_tile_32;
1274 } else if (vs->depth == 2) {
1275 vnc_write_u16(vs, 31); /* red-max */
1276 vnc_write_u16(vs, 63); /* green-max */
1277 vnc_write_u16(vs, 31); /* blue-max */
1278 vnc_write_u8(vs, 11); /* red-shift */
1279 vnc_write_u8(vs, 5); /* green-shift */
1280 vnc_write_u8(vs, 0); /* blue-shift */
1281 vs->send_hextile_tile = send_hextile_tile_16;
1282 } else if (vs->depth == 1) {
1283 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1284 vnc_write_u16(vs, 7); /* red-max */
1285 vnc_write_u16(vs, 7); /* green-max */
1286 vnc_write_u16(vs, 3); /* blue-max */
1287 vnc_write_u8(vs, 5); /* red-shift */
1288 vnc_write_u8(vs, 2); /* green-shift */
1289 vnc_write_u8(vs, 0); /* blue-shift */
1290 vs->send_hextile_tile = send_hextile_tile_8;
1292 vs->write_pixels = vnc_write_pixels_copy;
1294 vnc_write(vs, pad, 3); /* padding */
1296 if (qemu_name)
1297 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1298 else
1299 size = snprintf(buf, sizeof(buf), "QEMU");
1301 vnc_write_u32(vs, size);
1302 vnc_write(vs, buf, size);
1303 vnc_flush(vs);
1305 vnc_read_when(vs, protocol_client_msg, 1);
1307 return 0;
1310 static void make_challenge(VncState *vs)
1312 int i;
1314 srand(time(NULL)+getpid()+getpid()*987654+rand());
1316 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1317 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1320 static int protocol_client_auth_vnc(VncState *vs, char *data, size_t len)
1322 char response[VNC_AUTH_CHALLENGE_SIZE];
1323 int i, j, pwlen;
1324 char key[8];
1326 if (!vs->password || !vs->password[0]) {
1327 VNC_DEBUG("No password configured on server");
1328 vnc_write_u32(vs, 1); /* Reject auth */
1329 if (vs->minor >= 8) {
1330 static const char err[] = "Authentication failed";
1331 vnc_write_u32(vs, sizeof(err));
1332 vnc_write(vs, err, sizeof(err));
1334 vnc_flush(vs);
1335 vnc_client_error(vs);
1336 return 0;
1339 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1341 /* Calculate the expected challenge response */
1342 pwlen = strlen(vs->password);
1343 for (i=0; i<sizeof(key); i++)
1344 key[i] = i<pwlen ? vs->password[i] : 0;
1345 deskey(key, EN0);
1346 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1347 des(response+j, response+j);
1349 /* Compare expected vs actual challenge response */
1350 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1351 VNC_DEBUG("Client challenge reponse did not match\n");
1352 vnc_write_u32(vs, 1); /* Reject auth */
1353 if (vs->minor >= 8) {
1354 static const char err[] = "Authentication failed";
1355 vnc_write_u32(vs, sizeof(err));
1356 vnc_write(vs, err, sizeof(err));
1358 vnc_flush(vs);
1359 vnc_client_error(vs);
1360 } else {
1361 VNC_DEBUG("Accepting VNC challenge response\n");
1362 vnc_write_u32(vs, 0); /* Accept auth */
1363 vnc_flush(vs);
1365 vnc_read_when(vs, protocol_client_init, 1);
1367 return 0;
1370 static int start_auth_vnc(VncState *vs)
1372 make_challenge(vs);
1373 /* Send client a 'random' challenge */
1374 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1375 vnc_flush(vs);
1377 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1378 return 0;
1382 #if CONFIG_VNC_TLS
1383 #define DH_BITS 1024
1384 static gnutls_dh_params_t dh_params;
1386 static int vnc_tls_initialize(void)
1388 static int tlsinitialized = 0;
1390 if (tlsinitialized)
1391 return 1;
1393 if (gnutls_global_init () < 0)
1394 return 0;
1396 /* XXX ought to re-generate diffie-hellmen params periodically */
1397 if (gnutls_dh_params_init (&dh_params) < 0)
1398 return 0;
1399 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1400 return 0;
1402 #if _VNC_DEBUG == 2
1403 gnutls_global_set_log_level(10);
1404 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1405 #endif
1407 tlsinitialized = 1;
1409 return 1;
1412 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1414 gnutls_anon_server_credentials anon_cred;
1415 int ret;
1417 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1418 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1419 return NULL;
1422 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1424 return anon_cred;
1428 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1430 gnutls_certificate_credentials_t x509_cred;
1431 int ret;
1433 if (!vs->x509cacert) {
1434 VNC_DEBUG("No CA x509 certificate specified\n");
1435 return NULL;
1437 if (!vs->x509cert) {
1438 VNC_DEBUG("No server x509 certificate specified\n");
1439 return NULL;
1441 if (!vs->x509key) {
1442 VNC_DEBUG("No server private key specified\n");
1443 return NULL;
1446 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1447 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1448 return NULL;
1450 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1451 vs->x509cacert,
1452 GNUTLS_X509_FMT_PEM)) < 0) {
1453 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1454 gnutls_certificate_free_credentials(x509_cred);
1455 return NULL;
1458 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1459 vs->x509cert,
1460 vs->x509key,
1461 GNUTLS_X509_FMT_PEM)) < 0) {
1462 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1463 gnutls_certificate_free_credentials(x509_cred);
1464 return NULL;
1467 if (vs->x509cacrl) {
1468 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1469 vs->x509cacrl,
1470 GNUTLS_X509_FMT_PEM)) < 0) {
1471 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1472 gnutls_certificate_free_credentials(x509_cred);
1473 return NULL;
1477 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1479 return x509_cred;
1482 static int vnc_validate_certificate(struct VncState *vs)
1484 int ret;
1485 unsigned int status;
1486 const gnutls_datum_t *certs;
1487 unsigned int nCerts, i;
1488 time_t now;
1490 VNC_DEBUG("Validating client certificate\n");
1491 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1492 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1493 return -1;
1496 if ((now = time(NULL)) == ((time_t)-1)) {
1497 return -1;
1500 if (status != 0) {
1501 if (status & GNUTLS_CERT_INVALID)
1502 VNC_DEBUG("The certificate is not trusted.\n");
1504 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1505 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1507 if (status & GNUTLS_CERT_REVOKED)
1508 VNC_DEBUG("The certificate has been revoked.\n");
1510 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1511 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1513 return -1;
1514 } else {
1515 VNC_DEBUG("Certificate is valid!\n");
1518 /* Only support x509 for now */
1519 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1520 return -1;
1522 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1523 return -1;
1525 for (i = 0 ; i < nCerts ; i++) {
1526 gnutls_x509_crt_t cert;
1527 VNC_DEBUG ("Checking certificate chain %d\n", i);
1528 if (gnutls_x509_crt_init (&cert) < 0)
1529 return -1;
1531 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1532 gnutls_x509_crt_deinit (cert);
1533 return -1;
1536 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1537 VNC_DEBUG("The certificate has expired\n");
1538 gnutls_x509_crt_deinit (cert);
1539 return -1;
1542 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1543 VNC_DEBUG("The certificate is not yet activated\n");
1544 gnutls_x509_crt_deinit (cert);
1545 return -1;
1548 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1549 VNC_DEBUG("The certificate is not yet activated\n");
1550 gnutls_x509_crt_deinit (cert);
1551 return -1;
1554 gnutls_x509_crt_deinit (cert);
1557 return 0;
1561 static int start_auth_vencrypt_subauth(VncState *vs)
1563 switch (vs->subauth) {
1564 case VNC_AUTH_VENCRYPT_TLSNONE:
1565 case VNC_AUTH_VENCRYPT_X509NONE:
1566 VNC_DEBUG("Accept TLS auth none\n");
1567 vnc_write_u32(vs, 0); /* Accept auth completion */
1568 vnc_read_when(vs, protocol_client_init, 1);
1569 break;
1571 case VNC_AUTH_VENCRYPT_TLSVNC:
1572 case VNC_AUTH_VENCRYPT_X509VNC:
1573 VNC_DEBUG("Start TLS auth VNC\n");
1574 return start_auth_vnc(vs);
1576 default: /* Should not be possible, but just in case */
1577 VNC_DEBUG("Reject auth %d\n", vs->auth);
1578 vnc_write_u8(vs, 1);
1579 if (vs->minor >= 8) {
1580 static const char err[] = "Unsupported authentication type";
1581 vnc_write_u32(vs, sizeof(err));
1582 vnc_write(vs, err, sizeof(err));
1584 vnc_client_error(vs);
1587 return 0;
1590 static void vnc_handshake_io(void *opaque);
1592 static int vnc_continue_handshake(struct VncState *vs) {
1593 int ret;
1595 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1596 if (!gnutls_error_is_fatal(ret)) {
1597 VNC_DEBUG("Handshake interrupted (blocking)\n");
1598 if (!gnutls_record_get_direction(vs->tls_session))
1599 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1600 else
1601 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1602 return 0;
1604 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1605 vnc_client_error(vs);
1606 return -1;
1609 if (vs->x509verify) {
1610 if (vnc_validate_certificate(vs) < 0) {
1611 VNC_DEBUG("Client verification failed\n");
1612 vnc_client_error(vs);
1613 return -1;
1614 } else {
1615 VNC_DEBUG("Client verification passed\n");
1619 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1620 vs->wiremode = VNC_WIREMODE_TLS;
1621 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1623 return start_auth_vencrypt_subauth(vs);
1626 static void vnc_handshake_io(void *opaque) {
1627 struct VncState *vs = (struct VncState *)opaque;
1629 VNC_DEBUG("Handshake IO continue\n");
1630 vnc_continue_handshake(vs);
1633 #define NEED_X509_AUTH(vs) \
1634 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1635 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1636 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1639 static int vnc_start_tls(struct VncState *vs) {
1640 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1641 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1642 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1643 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1645 VNC_DEBUG("Do TLS setup\n");
1646 if (vnc_tls_initialize() < 0) {
1647 VNC_DEBUG("Failed to init TLS\n");
1648 vnc_client_error(vs);
1649 return -1;
1651 if (vs->tls_session == NULL) {
1652 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1653 vnc_client_error(vs);
1654 return -1;
1657 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1658 gnutls_deinit(vs->tls_session);
1659 vs->tls_session = NULL;
1660 vnc_client_error(vs);
1661 return -1;
1664 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1665 gnutls_deinit(vs->tls_session);
1666 vs->tls_session = NULL;
1667 vnc_client_error(vs);
1668 return -1;
1671 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1672 gnutls_deinit(vs->tls_session);
1673 vs->tls_session = NULL;
1674 vnc_client_error(vs);
1675 return -1;
1678 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1679 gnutls_deinit(vs->tls_session);
1680 vs->tls_session = NULL;
1681 vnc_client_error(vs);
1682 return -1;
1685 if (NEED_X509_AUTH(vs)) {
1686 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1687 if (!x509_cred) {
1688 gnutls_deinit(vs->tls_session);
1689 vs->tls_session = NULL;
1690 vnc_client_error(vs);
1691 return -1;
1693 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1694 gnutls_deinit(vs->tls_session);
1695 vs->tls_session = NULL;
1696 gnutls_certificate_free_credentials(x509_cred);
1697 vnc_client_error(vs);
1698 return -1;
1700 if (vs->x509verify) {
1701 VNC_DEBUG("Requesting a client certificate\n");
1702 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1705 } else {
1706 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1707 if (!anon_cred) {
1708 gnutls_deinit(vs->tls_session);
1709 vs->tls_session = NULL;
1710 vnc_client_error(vs);
1711 return -1;
1713 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1714 gnutls_deinit(vs->tls_session);
1715 vs->tls_session = NULL;
1716 gnutls_anon_free_server_credentials(anon_cred);
1717 vnc_client_error(vs);
1718 return -1;
1722 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1723 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1724 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1727 VNC_DEBUG("Start TLS handshake process\n");
1728 return vnc_continue_handshake(vs);
1731 static int protocol_client_vencrypt_auth(VncState *vs, char *data, size_t len)
1733 int auth = read_u32(data, 0);
1735 if (auth != vs->subauth) {
1736 VNC_DEBUG("Rejecting auth %d\n", auth);
1737 vnc_write_u8(vs, 0); /* Reject auth */
1738 vnc_flush(vs);
1739 vnc_client_error(vs);
1740 } else {
1741 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1742 vnc_write_u8(vs, 1); /* Accept auth */
1743 vnc_flush(vs);
1745 if (vnc_start_tls(vs) < 0) {
1746 VNC_DEBUG("Failed to complete TLS\n");
1747 return 0;
1750 if (vs->wiremode == VNC_WIREMODE_TLS) {
1751 VNC_DEBUG("Starting VeNCrypt subauth\n");
1752 return start_auth_vencrypt_subauth(vs);
1753 } else {
1754 VNC_DEBUG("TLS handshake blocked\n");
1755 return 0;
1758 return 0;
1761 static int protocol_client_vencrypt_init(VncState *vs, char *data, size_t len)
1763 if (data[0] != 0 ||
1764 data[1] != 2) {
1765 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1766 vnc_write_u8(vs, 1); /* Reject version */
1767 vnc_flush(vs);
1768 vnc_client_error(vs);
1769 } else {
1770 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1771 vnc_write_u8(vs, 0); /* Accept version */
1772 vnc_write_u8(vs, 1); /* Number of sub-auths */
1773 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1774 vnc_flush(vs);
1775 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1777 return 0;
1780 static int start_auth_vencrypt(VncState *vs)
1782 /* Send VeNCrypt version 0.2 */
1783 vnc_write_u8(vs, 0);
1784 vnc_write_u8(vs, 2);
1786 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1787 return 0;
1789 #endif /* CONFIG_VNC_TLS */
1791 static int protocol_client_auth(VncState *vs, char *data, size_t len)
1793 /* We only advertise 1 auth scheme at a time, so client
1794 * must pick the one we sent. Verify this */
1795 if (data[0] != vs->auth) { /* Reject auth */
1796 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1797 vnc_write_u32(vs, 1);
1798 if (vs->minor >= 8) {
1799 static const char err[] = "Authentication failed";
1800 vnc_write_u32(vs, sizeof(err));
1801 vnc_write(vs, err, sizeof(err));
1803 vnc_client_error(vs);
1804 } else { /* Accept requested auth */
1805 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1806 switch (vs->auth) {
1807 case VNC_AUTH_NONE:
1808 VNC_DEBUG("Accept auth none\n");
1809 if (vs->minor >= 8) {
1810 vnc_write_u32(vs, 0); /* Accept auth completion */
1811 vnc_flush(vs);
1813 vnc_read_when(vs, protocol_client_init, 1);
1814 break;
1816 case VNC_AUTH_VNC:
1817 VNC_DEBUG("Start VNC auth\n");
1818 return start_auth_vnc(vs);
1820 #if CONFIG_VNC_TLS
1821 case VNC_AUTH_VENCRYPT:
1822 VNC_DEBUG("Accept VeNCrypt auth\n");;
1823 return start_auth_vencrypt(vs);
1824 #endif /* CONFIG_VNC_TLS */
1826 default: /* Should not be possible, but just in case */
1827 VNC_DEBUG("Reject auth %d\n", vs->auth);
1828 vnc_write_u8(vs, 1);
1829 if (vs->minor >= 8) {
1830 static const char err[] = "Authentication failed";
1831 vnc_write_u32(vs, sizeof(err));
1832 vnc_write(vs, err, sizeof(err));
1834 vnc_client_error(vs);
1837 return 0;
1840 static int protocol_version(VncState *vs, char *version, size_t len)
1842 char local[13];
1844 memcpy(local, version, 12);
1845 local[12] = 0;
1847 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1848 VNC_DEBUG("Malformed protocol version %s\n", local);
1849 vnc_client_error(vs);
1850 return 0;
1852 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1853 if (vs->major != 3 ||
1854 (vs->minor != 3 &&
1855 vs->minor != 4 &&
1856 vs->minor != 5 &&
1857 vs->minor != 7 &&
1858 vs->minor != 8)) {
1859 VNC_DEBUG("Unsupported client version\n");
1860 vnc_write_u32(vs, VNC_AUTH_INVALID);
1861 vnc_flush(vs);
1862 vnc_client_error(vs);
1863 return 0;
1865 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1866 * as equivalent to v3.3 by servers
1868 if (vs->minor == 4 || vs->minor == 5)
1869 vs->minor = 3;
1871 if (vs->minor == 3) {
1872 if (vs->auth == VNC_AUTH_NONE) {
1873 VNC_DEBUG("Tell client auth none\n");
1874 vnc_write_u32(vs, vs->auth);
1875 vnc_flush(vs);
1876 vnc_read_when(vs, protocol_client_init, 1);
1877 } else if (vs->auth == VNC_AUTH_VNC) {
1878 VNC_DEBUG("Tell client VNC auth\n");
1879 vnc_write_u32(vs, vs->auth);
1880 vnc_flush(vs);
1881 start_auth_vnc(vs);
1882 } else {
1883 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1884 vnc_write_u32(vs, VNC_AUTH_INVALID);
1885 vnc_flush(vs);
1886 vnc_client_error(vs);
1888 } else {
1889 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1890 vnc_write_u8(vs, 1); /* num auth */
1891 vnc_write_u8(vs, vs->auth);
1892 vnc_read_when(vs, protocol_client_auth, 1);
1893 vnc_flush(vs);
1896 return 0;
1899 static void vnc_listen_read(void *opaque)
1901 VncState *vs = opaque;
1902 struct sockaddr_in addr;
1903 socklen_t addrlen = sizeof(addr);
1905 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1906 if (vs->csock != -1) {
1907 VNC_DEBUG("New client on socket %d\n", vs->csock);
1908 socket_set_nonblock(vs->csock);
1909 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
1910 vnc_write(vs, "RFB 003.008\n", 12);
1911 vnc_flush(vs);
1912 vnc_read_when(vs, protocol_version, 12);
1913 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1914 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1915 vs->has_resize = 0;
1916 vs->has_hextile = 0;
1917 vs->ds->dpy_copy = NULL;
1921 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1923 void vnc_display_init(DisplayState *ds)
1925 VncState *vs;
1927 vs = qemu_mallocz(sizeof(VncState));
1928 if (!vs)
1929 exit(1);
1931 ds->opaque = vs;
1932 vnc_state = vs;
1933 vs->display = NULL;
1934 vs->password = NULL;
1936 vs->lsock = -1;
1937 vs->csock = -1;
1938 vs->depth = 4;
1939 vs->last_x = -1;
1940 vs->last_y = -1;
1942 vs->ds = ds;
1944 if (!keyboard_layout)
1945 keyboard_layout = "en-us";
1947 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1948 if (!vs->kbd_layout)
1949 exit(1);
1951 vs->ds->data = NULL;
1952 vs->ds->dpy_update = vnc_dpy_update;
1953 vs->ds->dpy_resize = vnc_dpy_resize;
1954 vs->ds->dpy_refresh = vnc_dpy_refresh;
1956 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1958 vnc_dpy_resize(vs->ds, 640, 400);
1961 #if CONFIG_VNC_TLS
1962 static int vnc_set_x509_credential(VncState *vs,
1963 const char *certdir,
1964 const char *filename,
1965 char **cred,
1966 int ignoreMissing)
1968 struct stat sb;
1970 if (*cred) {
1971 qemu_free(*cred);
1972 *cred = NULL;
1975 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
1976 return -1;
1978 strcpy(*cred, certdir);
1979 strcat(*cred, "/");
1980 strcat(*cred, filename);
1982 VNC_DEBUG("Check %s\n", *cred);
1983 if (stat(*cred, &sb) < 0) {
1984 qemu_free(*cred);
1985 *cred = NULL;
1986 if (ignoreMissing && errno == ENOENT)
1987 return 0;
1988 return -1;
1991 return 0;
1994 static int vnc_set_x509_credential_dir(VncState *vs,
1995 const char *certdir)
1997 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
1998 goto cleanup;
1999 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2000 goto cleanup;
2001 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2002 goto cleanup;
2003 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2004 goto cleanup;
2006 return 0;
2008 cleanup:
2009 qemu_free(vs->x509cacert);
2010 qemu_free(vs->x509cacrl);
2011 qemu_free(vs->x509cert);
2012 qemu_free(vs->x509key);
2013 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2014 return -1;
2016 #endif /* CONFIG_VNC_TLS */
2018 void vnc_display_close(DisplayState *ds)
2020 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2022 if (vs->display) {
2023 qemu_free(vs->display);
2024 vs->display = NULL;
2026 if (vs->lsock != -1) {
2027 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2028 close(vs->lsock);
2029 vs->lsock = -1;
2031 if (vs->csock != -1) {
2032 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2033 closesocket(vs->csock);
2034 vs->csock = -1;
2035 buffer_reset(&vs->input);
2036 buffer_reset(&vs->output);
2037 vs->need_update = 0;
2038 #if CONFIG_VNC_TLS
2039 if (vs->tls_session) {
2040 gnutls_deinit(vs->tls_session);
2041 vs->tls_session = NULL;
2043 vs->wiremode = VNC_WIREMODE_CLEAR;
2044 #endif /* CONFIG_VNC_TLS */
2046 vs->auth = VNC_AUTH_INVALID;
2047 #if CONFIG_VNC_TLS
2048 vs->subauth = VNC_AUTH_INVALID;
2049 vs->x509verify = 0;
2050 #endif
2053 int vnc_display_password(DisplayState *ds, const char *password)
2055 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2057 if (vs->password) {
2058 qemu_free(vs->password);
2059 vs->password = NULL;
2061 if (password && password[0]) {
2062 if (!(vs->password = qemu_strdup(password)))
2063 return -1;
2066 return 0;
2069 int vnc_display_open(DisplayState *ds, const char *display)
2071 struct sockaddr *addr;
2072 struct sockaddr_in iaddr;
2073 #ifndef _WIN32
2074 struct sockaddr_un uaddr;
2075 #endif
2076 int reuse_addr, ret;
2077 socklen_t addrlen;
2078 const char *p;
2079 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2080 const char *options;
2081 int password = 0;
2082 #if CONFIG_VNC_TLS
2083 int tls = 0, x509 = 0;
2084 #endif
2086 vnc_display_close(ds);
2087 if (strcmp(display, "none") == 0)
2088 return 0;
2090 if (!(vs->display = strdup(display)))
2091 return -1;
2093 options = display;
2094 while ((options = strchr(options, ','))) {
2095 options++;
2096 if (strncmp(options, "password", 8) == 0) {
2097 password = 1; /* Require password auth */
2098 #if CONFIG_VNC_TLS
2099 } else if (strncmp(options, "tls", 3) == 0) {
2100 tls = 1; /* Require TLS */
2101 } else if (strncmp(options, "x509", 4) == 0) {
2102 char *start, *end;
2103 x509 = 1; /* Require x509 certificates */
2104 if (strncmp(options, "x509verify", 10) == 0)
2105 vs->x509verify = 1; /* ...and verify client certs */
2107 /* Now check for 'x509=/some/path' postfix
2108 * and use that to setup x509 certificate/key paths */
2109 start = strchr(options, '=');
2110 end = strchr(options, ',');
2111 if (start && (!end || (start < end))) {
2112 int len = end ? end-(start+1) : strlen(start+1);
2113 char *path = qemu_malloc(len+1);
2114 strncpy(path, start+1, len);
2115 path[len] = '\0';
2116 VNC_DEBUG("Trying certificate path '%s'\n", path);
2117 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2118 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2119 qemu_free(path);
2120 qemu_free(vs->display);
2121 vs->display = NULL;
2122 return -1;
2124 qemu_free(path);
2125 } else {
2126 fprintf(stderr, "No certificate path provided\n");
2127 qemu_free(vs->display);
2128 vs->display = NULL;
2129 return -1;
2131 #endif
2135 if (password) {
2136 #if CONFIG_VNC_TLS
2137 if (tls) {
2138 vs->auth = VNC_AUTH_VENCRYPT;
2139 if (x509) {
2140 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2141 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2142 } else {
2143 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2144 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2146 } else {
2147 #endif
2148 VNC_DEBUG("Initializing VNC server with password auth\n");
2149 vs->auth = VNC_AUTH_VNC;
2150 #if CONFIG_VNC_TLS
2151 vs->subauth = VNC_AUTH_INVALID;
2153 #endif
2154 } else {
2155 #if CONFIG_VNC_TLS
2156 if (tls) {
2157 vs->auth = VNC_AUTH_VENCRYPT;
2158 if (x509) {
2159 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2160 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2161 } else {
2162 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2163 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2165 } else {
2166 #endif
2167 VNC_DEBUG("Initializing VNC server with no auth\n");
2168 vs->auth = VNC_AUTH_NONE;
2169 #if CONFIG_VNC_TLS
2170 vs->subauth = VNC_AUTH_INVALID;
2172 #endif
2174 #ifndef _WIN32
2175 if (strstart(display, "unix:", &p)) {
2176 addr = (struct sockaddr *)&uaddr;
2177 addrlen = sizeof(uaddr);
2179 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2180 if (vs->lsock == -1) {
2181 fprintf(stderr, "Could not create socket\n");
2182 free(vs->display);
2183 vs->display = NULL;
2184 return -1;
2187 uaddr.sun_family = AF_UNIX;
2188 memset(uaddr.sun_path, 0, 108);
2189 snprintf(uaddr.sun_path, 108, "%s", p);
2191 unlink(uaddr.sun_path);
2192 } else
2193 #endif
2195 addr = (struct sockaddr *)&iaddr;
2196 addrlen = sizeof(iaddr);
2198 if (parse_host_port(&iaddr, display) < 0) {
2199 fprintf(stderr, "Could not parse VNC address\n");
2200 free(vs->display);
2201 vs->display = NULL;
2202 return -1;
2205 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
2207 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2208 if (vs->lsock == -1) {
2209 fprintf(stderr, "Could not create socket\n");
2210 free(vs->display);
2211 vs->display = NULL;
2212 return -1;
2215 reuse_addr = 1;
2216 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2217 (const char *)&reuse_addr, sizeof(reuse_addr));
2218 if (ret == -1) {
2219 fprintf(stderr, "setsockopt() failed\n");
2220 close(vs->lsock);
2221 vs->lsock = -1;
2222 free(vs->display);
2223 vs->display = NULL;
2224 return -1;
2228 if (bind(vs->lsock, addr, addrlen) == -1) {
2229 fprintf(stderr, "bind() failed\n");
2230 close(vs->lsock);
2231 vs->lsock = -1;
2232 free(vs->display);
2233 vs->display = NULL;
2234 return -1;
2237 if (listen(vs->lsock, 1) == -1) {
2238 fprintf(stderr, "listen() failed\n");
2239 close(vs->lsock);
2240 vs->lsock = -1;
2241 free(vs->display);
2242 vs->display = NULL;
2243 return -1;
2246 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);