Fix OpenBSD linker warnings in qemu-img
[qemu/mini2440.git] / vnc.c
blobc0a05a85f1cf88c316209100adf1c0ab73adfb36
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
26 #include "qemu-common.h"
27 #include "console.h"
28 #include "sysemu.h"
29 #include "qemu_socket.h"
30 #include "qemu-timer.h"
32 #define VNC_REFRESH_INTERVAL (1000 / 30)
34 #include "vnc_keysym.h"
35 #include "keymaps.c"
36 #include "d3des.h"
38 #if CONFIG_VNC_TLS
39 #include <gnutls/gnutls.h>
40 #include <gnutls/x509.h>
41 #endif /* CONFIG_VNC_TLS */
43 // #define _VNC_DEBUG 1
45 #if _VNC_DEBUG
46 #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
48 #if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
49 /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
50 static void vnc_debug_gnutls_log(int level, const char* str) {
51 VNC_DEBUG("%d %s", level, str);
53 #endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
54 #else
55 #define VNC_DEBUG(fmt, ...) do { } while (0)
56 #endif
59 typedef struct Buffer
61 size_t capacity;
62 size_t offset;
63 uint8_t *buffer;
64 } Buffer;
66 typedef struct VncState VncState;
68 typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
70 typedef void VncWritePixels(VncState *vs, void *data, int size);
72 typedef void VncSendHextileTile(VncState *vs,
73 int x, int y, int w, int h,
74 uint32_t *last_bg,
75 uint32_t *last_fg,
76 int *has_bg, int *has_fg);
78 #define VNC_MAX_WIDTH 2048
79 #define VNC_MAX_HEIGHT 2048
80 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
82 #define VNC_AUTH_CHALLENGE_SIZE 16
84 enum {
85 VNC_AUTH_INVALID = 0,
86 VNC_AUTH_NONE = 1,
87 VNC_AUTH_VNC = 2,
88 VNC_AUTH_RA2 = 5,
89 VNC_AUTH_RA2NE = 6,
90 VNC_AUTH_TIGHT = 16,
91 VNC_AUTH_ULTRA = 17,
92 VNC_AUTH_TLS = 18,
93 VNC_AUTH_VENCRYPT = 19
96 #if CONFIG_VNC_TLS
97 enum {
98 VNC_WIREMODE_CLEAR,
99 VNC_WIREMODE_TLS,
102 enum {
103 VNC_AUTH_VENCRYPT_PLAIN = 256,
104 VNC_AUTH_VENCRYPT_TLSNONE = 257,
105 VNC_AUTH_VENCRYPT_TLSVNC = 258,
106 VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
107 VNC_AUTH_VENCRYPT_X509NONE = 260,
108 VNC_AUTH_VENCRYPT_X509VNC = 261,
109 VNC_AUTH_VENCRYPT_X509PLAIN = 262,
112 #if CONFIG_VNC_TLS
113 #define X509_CA_CERT_FILE "ca-cert.pem"
114 #define X509_CA_CRL_FILE "ca-crl.pem"
115 #define X509_SERVER_KEY_FILE "server-key.pem"
116 #define X509_SERVER_CERT_FILE "server-cert.pem"
117 #endif
119 #endif /* CONFIG_VNC_TLS */
121 struct VncState
123 QEMUTimer *timer;
124 int lsock;
125 int csock;
126 DisplayState *ds;
127 int need_update;
128 int width;
129 int height;
130 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
131 char *old_data;
132 int depth; /* internal VNC frame buffer byte per pixel */
133 int has_resize;
134 int has_hextile;
135 int has_pointer_type_change;
136 int absolute;
137 int last_x;
138 int last_y;
140 int major;
141 int minor;
143 char *display;
144 char *password;
145 int auth;
146 #if CONFIG_VNC_TLS
147 int subauth;
148 int x509verify;
150 char *x509cacert;
151 char *x509cacrl;
152 char *x509cert;
153 char *x509key;
154 #endif
155 char challenge[VNC_AUTH_CHALLENGE_SIZE];
157 #if CONFIG_VNC_TLS
158 int wiremode;
159 gnutls_session_t tls_session;
160 #endif
162 Buffer output;
163 Buffer input;
164 kbd_layout_t *kbd_layout;
165 /* current output mode information */
166 VncWritePixels *write_pixels;
167 VncSendHextileTile *send_hextile_tile;
168 int pix_bpp, pix_big_endian;
169 int red_shift, red_max, red_shift1;
170 int green_shift, green_max, green_shift1;
171 int blue_shift, blue_max, blue_shift1;
173 VncReadEvent *read_handler;
174 size_t read_handler_expect;
175 /* input */
176 uint8_t modifiers_state[256];
179 static VncState *vnc_state; /* needed for info vnc */
181 void do_info_vnc(void)
183 if (vnc_state == NULL)
184 term_printf("VNC server disabled\n");
185 else {
186 term_printf("VNC server active on: ");
187 term_print_filename(vnc_state->display);
188 term_printf("\n");
190 if (vnc_state->csock == -1)
191 term_printf("No client connected\n");
192 else
193 term_printf("Client connected\n");
197 /* TODO
198 1) Get the queue working for IO.
199 2) there is some weirdness when using the -S option (the screen is grey
200 and not totally invalidated
201 3) resolutions > 1024
204 static void vnc_write(VncState *vs, const void *data, size_t len);
205 static void vnc_write_u32(VncState *vs, uint32_t value);
206 static void vnc_write_s32(VncState *vs, int32_t value);
207 static void vnc_write_u16(VncState *vs, uint16_t value);
208 static void vnc_write_u8(VncState *vs, uint8_t value);
209 static void vnc_flush(VncState *vs);
210 static void vnc_update_client(void *opaque);
211 static void vnc_client_read(void *opaque);
213 static inline void vnc_set_bit(uint32_t *d, int k)
215 d[k >> 5] |= 1 << (k & 0x1f);
218 static inline void vnc_clear_bit(uint32_t *d, int k)
220 d[k >> 5] &= ~(1 << (k & 0x1f));
223 static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
225 int j;
227 j = 0;
228 while (n >= 32) {
229 d[j++] = -1;
230 n -= 32;
232 if (n > 0)
233 d[j++] = (1 << n) - 1;
234 while (j < nb_words)
235 d[j++] = 0;
238 static inline int vnc_get_bit(const uint32_t *d, int k)
240 return (d[k >> 5] >> (k & 0x1f)) & 1;
243 static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
244 int nb_words)
246 int i;
247 for(i = 0; i < nb_words; i++) {
248 if ((d1[i] & d2[i]) != 0)
249 return 1;
251 return 0;
254 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
256 VncState *vs = ds->opaque;
257 int i;
259 h += y;
261 /* round x down to ensure the loop only spans one 16-pixel block per,
262 iteration. otherwise, if (x % 16) != 0, the last iteration may span
263 two 16-pixel blocks but we only mark the first as dirty
265 w += (x % 16);
266 x -= (x % 16);
268 x = MIN(x, vs->width);
269 y = MIN(y, vs->height);
270 w = MIN(x + w, vs->width) - x;
271 h = MIN(h, vs->height);
273 for (; y < h; y++)
274 for (i = 0; i < w; i += 16)
275 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
278 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
279 int32_t encoding)
281 vnc_write_u16(vs, x);
282 vnc_write_u16(vs, y);
283 vnc_write_u16(vs, w);
284 vnc_write_u16(vs, h);
286 vnc_write_s32(vs, encoding);
289 static void vnc_dpy_resize(DisplayState *ds, int w, int h)
291 int size_changed;
292 VncState *vs = ds->opaque;
294 ds->data = qemu_realloc(ds->data, w * h * vs->depth);
295 vs->old_data = qemu_realloc(vs->old_data, w * h * vs->depth);
297 if (ds->data == NULL || vs->old_data == NULL) {
298 fprintf(stderr, "vnc: memory allocation failed\n");
299 exit(1);
302 if (ds->depth != vs->depth * 8) {
303 ds->depth = vs->depth * 8;
304 console_color_init(ds);
306 size_changed = ds->width != w || ds->height != h;
307 ds->width = w;
308 ds->height = h;
309 ds->linesize = w * vs->depth;
310 if (size_changed) {
311 vs->width = ds->width;
312 vs->height = ds->height;
313 if (vs->csock != -1 && vs->has_resize) {
314 vnc_write_u8(vs, 0); /* msg id */
315 vnc_write_u8(vs, 0);
316 vnc_write_u16(vs, 1); /* number of rects */
317 vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
318 vnc_flush(vs);
322 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
323 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
326 /* fastest code */
327 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
329 vnc_write(vs, pixels, size);
332 /* slowest but generic code. */
333 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
335 unsigned int r, g, b;
337 r = (v >> vs->red_shift1) & vs->red_max;
338 g = (v >> vs->green_shift1) & vs->green_max;
339 b = (v >> vs->blue_shift1) & vs->blue_max;
340 v = (r << vs->red_shift) |
341 (g << vs->green_shift) |
342 (b << vs->blue_shift);
343 switch(vs->pix_bpp) {
344 case 1:
345 buf[0] = v;
346 break;
347 case 2:
348 if (vs->pix_big_endian) {
349 buf[0] = v >> 8;
350 buf[1] = v;
351 } else {
352 buf[1] = v >> 8;
353 buf[0] = v;
355 break;
356 default:
357 case 4:
358 if (vs->pix_big_endian) {
359 buf[0] = v >> 24;
360 buf[1] = v >> 16;
361 buf[2] = v >> 8;
362 buf[3] = v;
363 } else {
364 buf[3] = v >> 24;
365 buf[2] = v >> 16;
366 buf[1] = v >> 8;
367 buf[0] = v;
369 break;
373 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
375 uint32_t *pixels = pixels1;
376 uint8_t buf[4];
377 int n, i;
379 n = size >> 2;
380 for(i = 0; i < n; i++) {
381 vnc_convert_pixel(vs, buf, pixels[i]);
382 vnc_write(vs, buf, vs->pix_bpp);
386 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
388 int i;
389 uint8_t *row;
391 vnc_framebuffer_update(vs, x, y, w, h, 0);
393 row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
394 for (i = 0; i < h; i++) {
395 vs->write_pixels(vs, row, w * vs->depth);
396 row += vs->ds->linesize;
400 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
402 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
403 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
406 #define BPP 8
407 #include "vnchextile.h"
408 #undef BPP
410 #define BPP 16
411 #include "vnchextile.h"
412 #undef BPP
414 #define BPP 32
415 #include "vnchextile.h"
416 #undef BPP
418 #define GENERIC
419 #define BPP 32
420 #include "vnchextile.h"
421 #undef BPP
422 #undef GENERIC
424 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
426 int i, j;
427 int has_fg, has_bg;
428 uint32_t last_fg32, last_bg32;
430 vnc_framebuffer_update(vs, x, y, w, h, 5);
432 has_fg = has_bg = 0;
433 for (j = y; j < (y + h); j += 16) {
434 for (i = x; i < (x + w); i += 16) {
435 vs->send_hextile_tile(vs, i, j,
436 MIN(16, x + w - i), MIN(16, y + h - j),
437 &last_bg32, &last_fg32, &has_bg, &has_fg);
442 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
444 if (vs->has_hextile)
445 send_framebuffer_update_hextile(vs, x, y, w, h);
446 else
447 send_framebuffer_update_raw(vs, x, y, w, h);
450 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
452 int src, dst;
453 uint8_t *src_row;
454 uint8_t *dst_row;
455 char *old_row;
456 int y = 0;
457 int pitch = ds->linesize;
458 VncState *vs = ds->opaque;
460 vnc_update_client(vs);
462 if (dst_y > src_y) {
463 y = h - 1;
464 pitch = -pitch;
467 src = (ds->linesize * (src_y + y) + vs->depth * src_x);
468 dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
470 src_row = ds->data + src;
471 dst_row = ds->data + dst;
472 old_row = vs->old_data + dst;
474 for (y = 0; y < h; y++) {
475 memmove(old_row, src_row, w * vs->depth);
476 memmove(dst_row, src_row, w * vs->depth);
477 src_row += pitch;
478 dst_row += pitch;
479 old_row += pitch;
482 vnc_write_u8(vs, 0); /* msg id */
483 vnc_write_u8(vs, 0);
484 vnc_write_u16(vs, 1); /* number of rects */
485 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
486 vnc_write_u16(vs, src_x);
487 vnc_write_u16(vs, src_y);
488 vnc_flush(vs);
491 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
493 int h;
495 for (h = 1; h < (vs->height - y); h++) {
496 int tmp_x;
497 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
498 break;
499 for (tmp_x = last_x; tmp_x < x; tmp_x++)
500 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
503 return h;
506 static void vnc_update_client(void *opaque)
508 VncState *vs = opaque;
510 if (vs->need_update && vs->csock != -1) {
511 int y;
512 uint8_t *row;
513 char *old_row;
514 uint32_t width_mask[VNC_DIRTY_WORDS];
515 int n_rectangles;
516 int saved_offset;
517 int has_dirty = 0;
519 vga_hw_update();
521 vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
523 /* Walk through the dirty map and eliminate tiles that
524 really aren't dirty */
525 row = vs->ds->data;
526 old_row = vs->old_data;
528 for (y = 0; y < vs->height; y++) {
529 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
530 int x;
531 uint8_t *ptr;
532 char *old_ptr;
534 ptr = row;
535 old_ptr = (char*)old_row;
537 for (x = 0; x < vs->ds->width; x += 16) {
538 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
539 vnc_clear_bit(vs->dirty_row[y], (x / 16));
540 } else {
541 has_dirty = 1;
542 memcpy(old_ptr, ptr, 16 * vs->depth);
545 ptr += 16 * vs->depth;
546 old_ptr += 16 * vs->depth;
550 row += vs->ds->linesize;
551 old_row += vs->ds->linesize;
554 if (!has_dirty) {
555 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
556 return;
559 /* Count rectangles */
560 n_rectangles = 0;
561 vnc_write_u8(vs, 0); /* msg id */
562 vnc_write_u8(vs, 0);
563 saved_offset = vs->output.offset;
564 vnc_write_u16(vs, 0);
566 for (y = 0; y < vs->height; y++) {
567 int x;
568 int last_x = -1;
569 for (x = 0; x < vs->width / 16; x++) {
570 if (vnc_get_bit(vs->dirty_row[y], x)) {
571 if (last_x == -1) {
572 last_x = x;
574 vnc_clear_bit(vs->dirty_row[y], x);
575 } else {
576 if (last_x != -1) {
577 int h = find_dirty_height(vs, y, last_x, x);
578 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
579 n_rectangles++;
581 last_x = -1;
584 if (last_x != -1) {
585 int h = find_dirty_height(vs, y, last_x, x);
586 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
587 n_rectangles++;
590 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
591 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
592 vnc_flush(vs);
596 if (vs->csock != -1) {
597 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
602 static int vnc_listen_poll(void *opaque)
604 VncState *vs = opaque;
605 if (vs->csock == -1)
606 return 1;
607 return 0;
610 static void buffer_reserve(Buffer *buffer, size_t len)
612 if ((buffer->capacity - buffer->offset) < len) {
613 buffer->capacity += (len + 1024);
614 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
615 if (buffer->buffer == NULL) {
616 fprintf(stderr, "vnc: out of memory\n");
617 exit(1);
622 static int buffer_empty(Buffer *buffer)
624 return buffer->offset == 0;
627 static uint8_t *buffer_end(Buffer *buffer)
629 return buffer->buffer + buffer->offset;
632 static void buffer_reset(Buffer *buffer)
634 buffer->offset = 0;
637 static void buffer_append(Buffer *buffer, const void *data, size_t len)
639 memcpy(buffer->buffer + buffer->offset, data, len);
640 buffer->offset += len;
643 static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
645 if (ret == 0 || ret == -1) {
646 if (ret == -1) {
647 switch (last_errno) {
648 case EINTR:
649 case EAGAIN:
650 #ifdef _WIN32
651 case WSAEWOULDBLOCK:
652 #endif
653 return 0;
654 default:
655 break;
659 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
660 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
661 closesocket(vs->csock);
662 vs->csock = -1;
663 vs->ds->idle = 1;
664 buffer_reset(&vs->input);
665 buffer_reset(&vs->output);
666 vs->need_update = 0;
667 #if CONFIG_VNC_TLS
668 if (vs->tls_session) {
669 gnutls_deinit(vs->tls_session);
670 vs->tls_session = NULL;
672 vs->wiremode = VNC_WIREMODE_CLEAR;
673 #endif /* CONFIG_VNC_TLS */
674 return 0;
676 return ret;
679 static void vnc_client_error(VncState *vs)
681 vnc_client_io_error(vs, -1, EINVAL);
684 static void vnc_client_write(void *opaque)
686 long ret;
687 VncState *vs = opaque;
689 #if CONFIG_VNC_TLS
690 if (vs->tls_session) {
691 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
692 if (ret < 0) {
693 if (ret == GNUTLS_E_AGAIN)
694 errno = EAGAIN;
695 else
696 errno = EIO;
697 ret = -1;
699 } else
700 #endif /* CONFIG_VNC_TLS */
701 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
702 ret = vnc_client_io_error(vs, ret, socket_error());
703 if (!ret)
704 return;
706 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
707 vs->output.offset -= ret;
709 if (vs->output.offset == 0) {
710 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
714 static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
716 vs->read_handler = func;
717 vs->read_handler_expect = expecting;
720 static void vnc_client_read(void *opaque)
722 VncState *vs = opaque;
723 long ret;
725 buffer_reserve(&vs->input, 4096);
727 #if CONFIG_VNC_TLS
728 if (vs->tls_session) {
729 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
730 if (ret < 0) {
731 if (ret == GNUTLS_E_AGAIN)
732 errno = EAGAIN;
733 else
734 errno = EIO;
735 ret = -1;
737 } else
738 #endif /* CONFIG_VNC_TLS */
739 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
740 ret = vnc_client_io_error(vs, ret, socket_error());
741 if (!ret)
742 return;
744 vs->input.offset += ret;
746 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
747 size_t len = vs->read_handler_expect;
748 int ret;
750 ret = vs->read_handler(vs, vs->input.buffer, len);
751 if (vs->csock == -1)
752 return;
754 if (!ret) {
755 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
756 vs->input.offset -= len;
757 } else {
758 vs->read_handler_expect = ret;
763 static void vnc_write(VncState *vs, const void *data, size_t len)
765 buffer_reserve(&vs->output, len);
767 if (buffer_empty(&vs->output)) {
768 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
771 buffer_append(&vs->output, data, len);
774 static void vnc_write_s32(VncState *vs, int32_t value)
776 vnc_write_u32(vs, *(uint32_t *)&value);
779 static void vnc_write_u32(VncState *vs, uint32_t value)
781 uint8_t buf[4];
783 buf[0] = (value >> 24) & 0xFF;
784 buf[1] = (value >> 16) & 0xFF;
785 buf[2] = (value >> 8) & 0xFF;
786 buf[3] = value & 0xFF;
788 vnc_write(vs, buf, 4);
791 static void vnc_write_u16(VncState *vs, uint16_t value)
793 uint8_t buf[2];
795 buf[0] = (value >> 8) & 0xFF;
796 buf[1] = value & 0xFF;
798 vnc_write(vs, buf, 2);
801 static void vnc_write_u8(VncState *vs, uint8_t value)
803 vnc_write(vs, (char *)&value, 1);
806 static void vnc_flush(VncState *vs)
808 if (vs->output.offset)
809 vnc_client_write(vs);
812 static uint8_t read_u8(uint8_t *data, size_t offset)
814 return data[offset];
817 static uint16_t read_u16(uint8_t *data, size_t offset)
819 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
822 static int32_t read_s32(uint8_t *data, size_t offset)
824 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
825 (data[offset + 2] << 8) | data[offset + 3]);
828 static uint32_t read_u32(uint8_t *data, size_t offset)
830 return ((data[offset] << 24) | (data[offset + 1] << 16) |
831 (data[offset + 2] << 8) | data[offset + 3]);
834 #if CONFIG_VNC_TLS
835 static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
836 const void *data,
837 size_t len) {
838 struct VncState *vs = (struct VncState *)transport;
839 int ret;
841 retry:
842 ret = send(vs->csock, data, len, 0);
843 if (ret < 0) {
844 if (errno == EINTR)
845 goto retry;
846 return -1;
848 return ret;
852 static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
853 void *data,
854 size_t len) {
855 struct VncState *vs = (struct VncState *)transport;
856 int ret;
858 retry:
859 ret = recv(vs->csock, data, len, 0);
860 if (ret < 0) {
861 if (errno == EINTR)
862 goto retry;
863 return -1;
865 return ret;
867 #endif /* CONFIG_VNC_TLS */
869 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
873 static void check_pointer_type_change(VncState *vs, int absolute)
875 if (vs->has_pointer_type_change && vs->absolute != absolute) {
876 vnc_write_u8(vs, 0);
877 vnc_write_u8(vs, 0);
878 vnc_write_u16(vs, 1);
879 vnc_framebuffer_update(vs, absolute, 0,
880 vs->ds->width, vs->ds->height, -257);
881 vnc_flush(vs);
883 vs->absolute = absolute;
886 static void pointer_event(VncState *vs, int button_mask, int x, int y)
888 int buttons = 0;
889 int dz = 0;
891 if (button_mask & 0x01)
892 buttons |= MOUSE_EVENT_LBUTTON;
893 if (button_mask & 0x02)
894 buttons |= MOUSE_EVENT_MBUTTON;
895 if (button_mask & 0x04)
896 buttons |= MOUSE_EVENT_RBUTTON;
897 if (button_mask & 0x08)
898 dz = -1;
899 if (button_mask & 0x10)
900 dz = 1;
902 if (vs->absolute) {
903 kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
904 y * 0x7FFF / (vs->ds->height - 1),
905 dz, buttons);
906 } else if (vs->has_pointer_type_change) {
907 x -= 0x7FFF;
908 y -= 0x7FFF;
910 kbd_mouse_event(x, y, dz, buttons);
911 } else {
912 if (vs->last_x != -1)
913 kbd_mouse_event(x - vs->last_x,
914 y - vs->last_y,
915 dz, buttons);
916 vs->last_x = x;
917 vs->last_y = y;
920 check_pointer_type_change(vs, kbd_mouse_is_absolute());
923 static void reset_keys(VncState *vs)
925 int i;
926 for(i = 0; i < 256; i++) {
927 if (vs->modifiers_state[i]) {
928 if (i & 0x80)
929 kbd_put_keycode(0xe0);
930 kbd_put_keycode(i | 0x80);
931 vs->modifiers_state[i] = 0;
936 static void press_key(VncState *vs, int keysym)
938 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
939 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
942 static void do_key_event(VncState *vs, int down, int keycode, int sym)
944 /* QEMU console switch */
945 switch(keycode) {
946 case 0x2a: /* Left Shift */
947 case 0x36: /* Right Shift */
948 case 0x1d: /* Left CTRL */
949 case 0x9d: /* Right CTRL */
950 case 0x38: /* Left ALT */
951 case 0xb8: /* Right ALT */
952 if (down)
953 vs->modifiers_state[keycode] = 1;
954 else
955 vs->modifiers_state[keycode] = 0;
956 break;
957 case 0x02 ... 0x0a: /* '1' to '9' keys */
958 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
959 /* Reset the modifiers sent to the current console */
960 reset_keys(vs);
961 console_select(keycode - 0x02);
962 return;
964 break;
965 case 0x3a: /* CapsLock */
966 case 0x45: /* NumLock */
967 if (!down)
968 vs->modifiers_state[keycode] ^= 1;
969 break;
972 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
973 /* If the numlock state needs to change then simulate an additional
974 keypress before sending this one. This will happen if the user
975 toggles numlock away from the VNC window.
977 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
978 if (!vs->modifiers_state[0x45]) {
979 vs->modifiers_state[0x45] = 1;
980 press_key(vs, 0xff7f);
982 } else {
983 if (vs->modifiers_state[0x45]) {
984 vs->modifiers_state[0x45] = 0;
985 press_key(vs, 0xff7f);
990 if (is_graphic_console()) {
991 if (keycode & 0x80)
992 kbd_put_keycode(0xe0);
993 if (down)
994 kbd_put_keycode(keycode & 0x7f);
995 else
996 kbd_put_keycode(keycode | 0x80);
997 } else {
998 /* QEMU console emulation */
999 if (down) {
1000 switch (keycode) {
1001 case 0x2a: /* Left Shift */
1002 case 0x36: /* Right Shift */
1003 case 0x1d: /* Left CTRL */
1004 case 0x9d: /* Right CTRL */
1005 case 0x38: /* Left ALT */
1006 case 0xb8: /* Right ALT */
1007 break;
1008 case 0xc8:
1009 kbd_put_keysym(QEMU_KEY_UP);
1010 break;
1011 case 0xd0:
1012 kbd_put_keysym(QEMU_KEY_DOWN);
1013 break;
1014 case 0xcb:
1015 kbd_put_keysym(QEMU_KEY_LEFT);
1016 break;
1017 case 0xcd:
1018 kbd_put_keysym(QEMU_KEY_RIGHT);
1019 break;
1020 case 0xd3:
1021 kbd_put_keysym(QEMU_KEY_DELETE);
1022 break;
1023 case 0xc7:
1024 kbd_put_keysym(QEMU_KEY_HOME);
1025 break;
1026 case 0xcf:
1027 kbd_put_keysym(QEMU_KEY_END);
1028 break;
1029 case 0xc9:
1030 kbd_put_keysym(QEMU_KEY_PAGEUP);
1031 break;
1032 case 0xd1:
1033 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1034 break;
1035 default:
1036 kbd_put_keysym(sym);
1037 break;
1043 static void key_event(VncState *vs, int down, uint32_t sym)
1045 int keycode;
1047 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1048 sym = sym - 'A' + 'a';
1050 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
1051 do_key_event(vs, down, keycode, sym);
1054 static void ext_key_event(VncState *vs, int down,
1055 uint32_t sym, uint16_t keycode)
1057 /* if the user specifies a keyboard layout, always use it */
1058 if (keyboard_layout)
1059 key_event(vs, down, sym);
1060 else
1061 do_key_event(vs, down, keycode, sym);
1064 static void framebuffer_update_request(VncState *vs, int incremental,
1065 int x_position, int y_position,
1066 int w, int h)
1068 if (x_position > vs->ds->width)
1069 x_position = vs->ds->width;
1070 if (y_position > vs->ds->height)
1071 y_position = vs->ds->height;
1072 if (x_position + w >= vs->ds->width)
1073 w = vs->ds->width - x_position;
1074 if (y_position + h >= vs->ds->height)
1075 h = vs->ds->height - y_position;
1077 int i;
1078 vs->need_update = 1;
1079 if (!incremental) {
1080 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1082 for (i = 0; i < h; i++) {
1083 vnc_set_bits(vs->dirty_row[y_position + i],
1084 (vs->ds->width / 16), VNC_DIRTY_WORDS);
1085 memset(old_row, 42, vs->ds->width * vs->depth);
1086 old_row += vs->ds->linesize;
1091 static void send_ext_key_event_ack(VncState *vs)
1093 vnc_write_u8(vs, 0);
1094 vnc_write_u8(vs, 0);
1095 vnc_write_u16(vs, 1);
1096 vnc_framebuffer_update(vs, 0, 0, vs->ds->width, vs->ds->height, -258);
1097 vnc_flush(vs);
1100 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1102 int i;
1104 vs->has_hextile = 0;
1105 vs->has_resize = 0;
1106 vs->has_pointer_type_change = 0;
1107 vs->absolute = -1;
1108 vs->ds->dpy_copy = NULL;
1110 for (i = n_encodings - 1; i >= 0; i--) {
1111 switch (encodings[i]) {
1112 case 0: /* Raw */
1113 vs->has_hextile = 0;
1114 break;
1115 case 1: /* CopyRect */
1116 vs->ds->dpy_copy = vnc_copy;
1117 break;
1118 case 5: /* Hextile */
1119 vs->has_hextile = 1;
1120 break;
1121 case -223: /* DesktopResize */
1122 vs->has_resize = 1;
1123 break;
1124 case -257:
1125 vs->has_pointer_type_change = 1;
1126 break;
1127 case -258:
1128 send_ext_key_event_ack(vs);
1129 break;
1130 default:
1131 break;
1135 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1138 static int compute_nbits(unsigned int val)
1140 int n;
1141 n = 0;
1142 while (val != 0) {
1143 n++;
1144 val >>= 1;
1146 return n;
1149 static void set_pixel_format(VncState *vs,
1150 int bits_per_pixel, int depth,
1151 int big_endian_flag, int true_color_flag,
1152 int red_max, int green_max, int blue_max,
1153 int red_shift, int green_shift, int blue_shift)
1155 int host_big_endian_flag;
1157 #ifdef WORDS_BIGENDIAN
1158 host_big_endian_flag = 1;
1159 #else
1160 host_big_endian_flag = 0;
1161 #endif
1162 if (!true_color_flag) {
1163 fail:
1164 vnc_client_error(vs);
1165 return;
1167 if (bits_per_pixel == 32 &&
1168 host_big_endian_flag == big_endian_flag &&
1169 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1170 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1171 vs->depth = 4;
1172 vs->write_pixels = vnc_write_pixels_copy;
1173 vs->send_hextile_tile = send_hextile_tile_32;
1174 } else
1175 if (bits_per_pixel == 16 &&
1176 host_big_endian_flag == big_endian_flag &&
1177 red_max == 31 && green_max == 63 && blue_max == 31 &&
1178 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1179 vs->depth = 2;
1180 vs->write_pixels = vnc_write_pixels_copy;
1181 vs->send_hextile_tile = send_hextile_tile_16;
1182 } else
1183 if (bits_per_pixel == 8 &&
1184 red_max == 7 && green_max == 7 && blue_max == 3 &&
1185 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1186 vs->depth = 1;
1187 vs->write_pixels = vnc_write_pixels_copy;
1188 vs->send_hextile_tile = send_hextile_tile_8;
1189 } else
1191 /* generic and slower case */
1192 if (bits_per_pixel != 8 &&
1193 bits_per_pixel != 16 &&
1194 bits_per_pixel != 32)
1195 goto fail;
1196 vs->depth = 4;
1197 vs->red_shift = red_shift;
1198 vs->red_max = red_max;
1199 vs->red_shift1 = 24 - compute_nbits(red_max);
1200 vs->green_shift = green_shift;
1201 vs->green_max = green_max;
1202 vs->green_shift1 = 16 - compute_nbits(green_max);
1203 vs->blue_shift = blue_shift;
1204 vs->blue_max = blue_max;
1205 vs->blue_shift1 = 8 - compute_nbits(blue_max);
1206 vs->pix_bpp = bits_per_pixel / 8;
1207 vs->pix_big_endian = big_endian_flag;
1208 vs->write_pixels = vnc_write_pixels_generic;
1209 vs->send_hextile_tile = send_hextile_tile_generic;
1212 vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1214 vga_hw_invalidate();
1215 vga_hw_update();
1218 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1220 int i;
1221 uint16_t limit;
1223 switch (data[0]) {
1224 case 0:
1225 if (len == 1)
1226 return 20;
1228 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1229 read_u8(data, 6), read_u8(data, 7),
1230 read_u16(data, 8), read_u16(data, 10),
1231 read_u16(data, 12), read_u8(data, 14),
1232 read_u8(data, 15), read_u8(data, 16));
1233 break;
1234 case 2:
1235 if (len == 1)
1236 return 4;
1238 if (len == 4)
1239 return 4 + (read_u16(data, 2) * 4);
1241 limit = read_u16(data, 2);
1242 for (i = 0; i < limit; i++) {
1243 int32_t val = read_s32(data, 4 + (i * 4));
1244 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1247 set_encodings(vs, (int32_t *)(data + 4), limit);
1248 break;
1249 case 3:
1250 if (len == 1)
1251 return 10;
1253 framebuffer_update_request(vs,
1254 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1255 read_u16(data, 6), read_u16(data, 8));
1256 break;
1257 case 4:
1258 if (len == 1)
1259 return 8;
1261 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1262 break;
1263 case 5:
1264 if (len == 1)
1265 return 6;
1267 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1268 break;
1269 case 6:
1270 if (len == 1)
1271 return 8;
1273 if (len == 8) {
1274 uint32_t dlen = read_u32(data, 4);
1275 if (dlen > 0)
1276 return 8 + dlen;
1279 client_cut_text(vs, read_u32(data, 4), data + 8);
1280 break;
1281 case 255:
1282 if (len == 1)
1283 return 2;
1285 switch (read_u8(data, 1)) {
1286 case 0:
1287 if (len == 2)
1288 return 12;
1290 ext_key_event(vs, read_u16(data, 2),
1291 read_u32(data, 4), read_u32(data, 8));
1292 break;
1293 default:
1294 printf("Msg: %d\n", read_u16(data, 0));
1295 vnc_client_error(vs);
1296 break;
1298 break;
1299 default:
1300 printf("Msg: %d\n", data[0]);
1301 vnc_client_error(vs);
1302 break;
1305 vnc_read_when(vs, protocol_client_msg, 1);
1306 return 0;
1309 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1311 char pad[3] = { 0, 0, 0 };
1312 char buf[1024];
1313 int size;
1315 vs->width = vs->ds->width;
1316 vs->height = vs->ds->height;
1317 vnc_write_u16(vs, vs->ds->width);
1318 vnc_write_u16(vs, vs->ds->height);
1320 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1321 vnc_write_u8(vs, vs->depth * 8); /* depth */
1322 #ifdef WORDS_BIGENDIAN
1323 vnc_write_u8(vs, 1); /* big-endian-flag */
1324 #else
1325 vnc_write_u8(vs, 0); /* big-endian-flag */
1326 #endif
1327 vnc_write_u8(vs, 1); /* true-color-flag */
1328 if (vs->depth == 4) {
1329 vnc_write_u16(vs, 0xFF); /* red-max */
1330 vnc_write_u16(vs, 0xFF); /* green-max */
1331 vnc_write_u16(vs, 0xFF); /* blue-max */
1332 vnc_write_u8(vs, 16); /* red-shift */
1333 vnc_write_u8(vs, 8); /* green-shift */
1334 vnc_write_u8(vs, 0); /* blue-shift */
1335 vs->send_hextile_tile = send_hextile_tile_32;
1336 } else if (vs->depth == 2) {
1337 vnc_write_u16(vs, 31); /* red-max */
1338 vnc_write_u16(vs, 63); /* green-max */
1339 vnc_write_u16(vs, 31); /* blue-max */
1340 vnc_write_u8(vs, 11); /* red-shift */
1341 vnc_write_u8(vs, 5); /* green-shift */
1342 vnc_write_u8(vs, 0); /* blue-shift */
1343 vs->send_hextile_tile = send_hextile_tile_16;
1344 } else if (vs->depth == 1) {
1345 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1346 vnc_write_u16(vs, 7); /* red-max */
1347 vnc_write_u16(vs, 7); /* green-max */
1348 vnc_write_u16(vs, 3); /* blue-max */
1349 vnc_write_u8(vs, 5); /* red-shift */
1350 vnc_write_u8(vs, 2); /* green-shift */
1351 vnc_write_u8(vs, 0); /* blue-shift */
1352 vs->send_hextile_tile = send_hextile_tile_8;
1354 vs->write_pixels = vnc_write_pixels_copy;
1356 vnc_write(vs, pad, 3); /* padding */
1358 if (qemu_name)
1359 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1360 else
1361 size = snprintf(buf, sizeof(buf), "QEMU");
1363 vnc_write_u32(vs, size);
1364 vnc_write(vs, buf, size);
1365 vnc_flush(vs);
1367 vnc_read_when(vs, protocol_client_msg, 1);
1369 return 0;
1372 static void make_challenge(VncState *vs)
1374 int i;
1376 srand(time(NULL)+getpid()+getpid()*987654+rand());
1378 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1379 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1382 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1384 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1385 int i, j, pwlen;
1386 unsigned char key[8];
1388 if (!vs->password || !vs->password[0]) {
1389 VNC_DEBUG("No password configured on server");
1390 vnc_write_u32(vs, 1); /* Reject auth */
1391 if (vs->minor >= 8) {
1392 static const char err[] = "Authentication failed";
1393 vnc_write_u32(vs, sizeof(err));
1394 vnc_write(vs, err, sizeof(err));
1396 vnc_flush(vs);
1397 vnc_client_error(vs);
1398 return 0;
1401 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1403 /* Calculate the expected challenge response */
1404 pwlen = strlen(vs->password);
1405 for (i=0; i<sizeof(key); i++)
1406 key[i] = i<pwlen ? vs->password[i] : 0;
1407 deskey(key, EN0);
1408 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1409 des(response+j, response+j);
1411 /* Compare expected vs actual challenge response */
1412 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1413 VNC_DEBUG("Client challenge reponse did not match\n");
1414 vnc_write_u32(vs, 1); /* Reject auth */
1415 if (vs->minor >= 8) {
1416 static const char err[] = "Authentication failed";
1417 vnc_write_u32(vs, sizeof(err));
1418 vnc_write(vs, err, sizeof(err));
1420 vnc_flush(vs);
1421 vnc_client_error(vs);
1422 } else {
1423 VNC_DEBUG("Accepting VNC challenge response\n");
1424 vnc_write_u32(vs, 0); /* Accept auth */
1425 vnc_flush(vs);
1427 vnc_read_when(vs, protocol_client_init, 1);
1429 return 0;
1432 static int start_auth_vnc(VncState *vs)
1434 make_challenge(vs);
1435 /* Send client a 'random' challenge */
1436 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1437 vnc_flush(vs);
1439 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1440 return 0;
1444 #if CONFIG_VNC_TLS
1445 #define DH_BITS 1024
1446 static gnutls_dh_params_t dh_params;
1448 static int vnc_tls_initialize(void)
1450 static int tlsinitialized = 0;
1452 if (tlsinitialized)
1453 return 1;
1455 if (gnutls_global_init () < 0)
1456 return 0;
1458 /* XXX ought to re-generate diffie-hellmen params periodically */
1459 if (gnutls_dh_params_init (&dh_params) < 0)
1460 return 0;
1461 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1462 return 0;
1464 #if _VNC_DEBUG == 2
1465 gnutls_global_set_log_level(10);
1466 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1467 #endif
1469 tlsinitialized = 1;
1471 return 1;
1474 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1476 gnutls_anon_server_credentials anon_cred;
1477 int ret;
1479 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1480 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1481 return NULL;
1484 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1486 return anon_cred;
1490 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1492 gnutls_certificate_credentials_t x509_cred;
1493 int ret;
1495 if (!vs->x509cacert) {
1496 VNC_DEBUG("No CA x509 certificate specified\n");
1497 return NULL;
1499 if (!vs->x509cert) {
1500 VNC_DEBUG("No server x509 certificate specified\n");
1501 return NULL;
1503 if (!vs->x509key) {
1504 VNC_DEBUG("No server private key specified\n");
1505 return NULL;
1508 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1509 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1510 return NULL;
1512 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1513 vs->x509cacert,
1514 GNUTLS_X509_FMT_PEM)) < 0) {
1515 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1516 gnutls_certificate_free_credentials(x509_cred);
1517 return NULL;
1520 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1521 vs->x509cert,
1522 vs->x509key,
1523 GNUTLS_X509_FMT_PEM)) < 0) {
1524 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1525 gnutls_certificate_free_credentials(x509_cred);
1526 return NULL;
1529 if (vs->x509cacrl) {
1530 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1531 vs->x509cacrl,
1532 GNUTLS_X509_FMT_PEM)) < 0) {
1533 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1534 gnutls_certificate_free_credentials(x509_cred);
1535 return NULL;
1539 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1541 return x509_cred;
1544 static int vnc_validate_certificate(struct VncState *vs)
1546 int ret;
1547 unsigned int status;
1548 const gnutls_datum_t *certs;
1549 unsigned int nCerts, i;
1550 time_t now;
1552 VNC_DEBUG("Validating client certificate\n");
1553 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1554 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1555 return -1;
1558 if ((now = time(NULL)) == ((time_t)-1)) {
1559 return -1;
1562 if (status != 0) {
1563 if (status & GNUTLS_CERT_INVALID)
1564 VNC_DEBUG("The certificate is not trusted.\n");
1566 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1567 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1569 if (status & GNUTLS_CERT_REVOKED)
1570 VNC_DEBUG("The certificate has been revoked.\n");
1572 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1573 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1575 return -1;
1576 } else {
1577 VNC_DEBUG("Certificate is valid!\n");
1580 /* Only support x509 for now */
1581 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1582 return -1;
1584 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1585 return -1;
1587 for (i = 0 ; i < nCerts ; i++) {
1588 gnutls_x509_crt_t cert;
1589 VNC_DEBUG ("Checking certificate chain %d\n", i);
1590 if (gnutls_x509_crt_init (&cert) < 0)
1591 return -1;
1593 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1594 gnutls_x509_crt_deinit (cert);
1595 return -1;
1598 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1599 VNC_DEBUG("The certificate has expired\n");
1600 gnutls_x509_crt_deinit (cert);
1601 return -1;
1604 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1605 VNC_DEBUG("The certificate is not yet activated\n");
1606 gnutls_x509_crt_deinit (cert);
1607 return -1;
1610 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1611 VNC_DEBUG("The certificate is not yet activated\n");
1612 gnutls_x509_crt_deinit (cert);
1613 return -1;
1616 gnutls_x509_crt_deinit (cert);
1619 return 0;
1623 static int start_auth_vencrypt_subauth(VncState *vs)
1625 switch (vs->subauth) {
1626 case VNC_AUTH_VENCRYPT_TLSNONE:
1627 case VNC_AUTH_VENCRYPT_X509NONE:
1628 VNC_DEBUG("Accept TLS auth none\n");
1629 vnc_write_u32(vs, 0); /* Accept auth completion */
1630 vnc_read_when(vs, protocol_client_init, 1);
1631 break;
1633 case VNC_AUTH_VENCRYPT_TLSVNC:
1634 case VNC_AUTH_VENCRYPT_X509VNC:
1635 VNC_DEBUG("Start TLS auth VNC\n");
1636 return start_auth_vnc(vs);
1638 default: /* Should not be possible, but just in case */
1639 VNC_DEBUG("Reject auth %d\n", vs->auth);
1640 vnc_write_u8(vs, 1);
1641 if (vs->minor >= 8) {
1642 static const char err[] = "Unsupported authentication type";
1643 vnc_write_u32(vs, sizeof(err));
1644 vnc_write(vs, err, sizeof(err));
1646 vnc_client_error(vs);
1649 return 0;
1652 static void vnc_handshake_io(void *opaque);
1654 static int vnc_continue_handshake(struct VncState *vs) {
1655 int ret;
1657 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1658 if (!gnutls_error_is_fatal(ret)) {
1659 VNC_DEBUG("Handshake interrupted (blocking)\n");
1660 if (!gnutls_record_get_direction(vs->tls_session))
1661 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1662 else
1663 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1664 return 0;
1666 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1667 vnc_client_error(vs);
1668 return -1;
1671 if (vs->x509verify) {
1672 if (vnc_validate_certificate(vs) < 0) {
1673 VNC_DEBUG("Client verification failed\n");
1674 vnc_client_error(vs);
1675 return -1;
1676 } else {
1677 VNC_DEBUG("Client verification passed\n");
1681 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1682 vs->wiremode = VNC_WIREMODE_TLS;
1683 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1685 return start_auth_vencrypt_subauth(vs);
1688 static void vnc_handshake_io(void *opaque) {
1689 struct VncState *vs = (struct VncState *)opaque;
1691 VNC_DEBUG("Handshake IO continue\n");
1692 vnc_continue_handshake(vs);
1695 #define NEED_X509_AUTH(vs) \
1696 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1697 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1698 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1701 static int vnc_start_tls(struct VncState *vs) {
1702 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1703 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1704 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1705 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1707 VNC_DEBUG("Do TLS setup\n");
1708 if (vnc_tls_initialize() < 0) {
1709 VNC_DEBUG("Failed to init TLS\n");
1710 vnc_client_error(vs);
1711 return -1;
1713 if (vs->tls_session == NULL) {
1714 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1715 vnc_client_error(vs);
1716 return -1;
1719 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1720 gnutls_deinit(vs->tls_session);
1721 vs->tls_session = NULL;
1722 vnc_client_error(vs);
1723 return -1;
1726 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1727 gnutls_deinit(vs->tls_session);
1728 vs->tls_session = NULL;
1729 vnc_client_error(vs);
1730 return -1;
1733 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1734 gnutls_deinit(vs->tls_session);
1735 vs->tls_session = NULL;
1736 vnc_client_error(vs);
1737 return -1;
1740 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1741 gnutls_deinit(vs->tls_session);
1742 vs->tls_session = NULL;
1743 vnc_client_error(vs);
1744 return -1;
1747 if (NEED_X509_AUTH(vs)) {
1748 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1749 if (!x509_cred) {
1750 gnutls_deinit(vs->tls_session);
1751 vs->tls_session = NULL;
1752 vnc_client_error(vs);
1753 return -1;
1755 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1756 gnutls_deinit(vs->tls_session);
1757 vs->tls_session = NULL;
1758 gnutls_certificate_free_credentials(x509_cred);
1759 vnc_client_error(vs);
1760 return -1;
1762 if (vs->x509verify) {
1763 VNC_DEBUG("Requesting a client certificate\n");
1764 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1767 } else {
1768 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1769 if (!anon_cred) {
1770 gnutls_deinit(vs->tls_session);
1771 vs->tls_session = NULL;
1772 vnc_client_error(vs);
1773 return -1;
1775 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1776 gnutls_deinit(vs->tls_session);
1777 vs->tls_session = NULL;
1778 gnutls_anon_free_server_credentials(anon_cred);
1779 vnc_client_error(vs);
1780 return -1;
1784 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1785 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1786 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1789 VNC_DEBUG("Start TLS handshake process\n");
1790 return vnc_continue_handshake(vs);
1793 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
1795 int auth = read_u32(data, 0);
1797 if (auth != vs->subauth) {
1798 VNC_DEBUG("Rejecting auth %d\n", auth);
1799 vnc_write_u8(vs, 0); /* Reject auth */
1800 vnc_flush(vs);
1801 vnc_client_error(vs);
1802 } else {
1803 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1804 vnc_write_u8(vs, 1); /* Accept auth */
1805 vnc_flush(vs);
1807 if (vnc_start_tls(vs) < 0) {
1808 VNC_DEBUG("Failed to complete TLS\n");
1809 return 0;
1812 if (vs->wiremode == VNC_WIREMODE_TLS) {
1813 VNC_DEBUG("Starting VeNCrypt subauth\n");
1814 return start_auth_vencrypt_subauth(vs);
1815 } else {
1816 VNC_DEBUG("TLS handshake blocked\n");
1817 return 0;
1820 return 0;
1823 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
1825 if (data[0] != 0 ||
1826 data[1] != 2) {
1827 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1828 vnc_write_u8(vs, 1); /* Reject version */
1829 vnc_flush(vs);
1830 vnc_client_error(vs);
1831 } else {
1832 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1833 vnc_write_u8(vs, 0); /* Accept version */
1834 vnc_write_u8(vs, 1); /* Number of sub-auths */
1835 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1836 vnc_flush(vs);
1837 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1839 return 0;
1842 static int start_auth_vencrypt(VncState *vs)
1844 /* Send VeNCrypt version 0.2 */
1845 vnc_write_u8(vs, 0);
1846 vnc_write_u8(vs, 2);
1848 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1849 return 0;
1851 #endif /* CONFIG_VNC_TLS */
1853 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1855 /* We only advertise 1 auth scheme at a time, so client
1856 * must pick the one we sent. Verify this */
1857 if (data[0] != vs->auth) { /* Reject auth */
1858 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1859 vnc_write_u32(vs, 1);
1860 if (vs->minor >= 8) {
1861 static const char err[] = "Authentication failed";
1862 vnc_write_u32(vs, sizeof(err));
1863 vnc_write(vs, err, sizeof(err));
1865 vnc_client_error(vs);
1866 } else { /* Accept requested auth */
1867 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1868 switch (vs->auth) {
1869 case VNC_AUTH_NONE:
1870 VNC_DEBUG("Accept auth none\n");
1871 if (vs->minor >= 8) {
1872 vnc_write_u32(vs, 0); /* Accept auth completion */
1873 vnc_flush(vs);
1875 vnc_read_when(vs, protocol_client_init, 1);
1876 break;
1878 case VNC_AUTH_VNC:
1879 VNC_DEBUG("Start VNC auth\n");
1880 return start_auth_vnc(vs);
1882 #if CONFIG_VNC_TLS
1883 case VNC_AUTH_VENCRYPT:
1884 VNC_DEBUG("Accept VeNCrypt auth\n");;
1885 return start_auth_vencrypt(vs);
1886 #endif /* CONFIG_VNC_TLS */
1888 default: /* Should not be possible, but just in case */
1889 VNC_DEBUG("Reject auth %d\n", vs->auth);
1890 vnc_write_u8(vs, 1);
1891 if (vs->minor >= 8) {
1892 static const char err[] = "Authentication failed";
1893 vnc_write_u32(vs, sizeof(err));
1894 vnc_write(vs, err, sizeof(err));
1896 vnc_client_error(vs);
1899 return 0;
1902 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1904 char local[13];
1906 memcpy(local, version, 12);
1907 local[12] = 0;
1909 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1910 VNC_DEBUG("Malformed protocol version %s\n", local);
1911 vnc_client_error(vs);
1912 return 0;
1914 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1915 if (vs->major != 3 ||
1916 (vs->minor != 3 &&
1917 vs->minor != 4 &&
1918 vs->minor != 5 &&
1919 vs->minor != 7 &&
1920 vs->minor != 8)) {
1921 VNC_DEBUG("Unsupported client version\n");
1922 vnc_write_u32(vs, VNC_AUTH_INVALID);
1923 vnc_flush(vs);
1924 vnc_client_error(vs);
1925 return 0;
1927 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1928 * as equivalent to v3.3 by servers
1930 if (vs->minor == 4 || vs->minor == 5)
1931 vs->minor = 3;
1933 if (vs->minor == 3) {
1934 if (vs->auth == VNC_AUTH_NONE) {
1935 VNC_DEBUG("Tell client auth none\n");
1936 vnc_write_u32(vs, vs->auth);
1937 vnc_flush(vs);
1938 vnc_read_when(vs, protocol_client_init, 1);
1939 } else if (vs->auth == VNC_AUTH_VNC) {
1940 VNC_DEBUG("Tell client VNC auth\n");
1941 vnc_write_u32(vs, vs->auth);
1942 vnc_flush(vs);
1943 start_auth_vnc(vs);
1944 } else {
1945 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1946 vnc_write_u32(vs, VNC_AUTH_INVALID);
1947 vnc_flush(vs);
1948 vnc_client_error(vs);
1950 } else {
1951 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1952 vnc_write_u8(vs, 1); /* num auth */
1953 vnc_write_u8(vs, vs->auth);
1954 vnc_read_when(vs, protocol_client_auth, 1);
1955 vnc_flush(vs);
1958 return 0;
1961 static void vnc_connect(VncState *vs)
1963 VNC_DEBUG("New client on socket %d\n", vs->csock);
1964 vs->ds->idle = 0;
1965 socket_set_nonblock(vs->csock);
1966 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1967 vnc_write(vs, "RFB 003.008\n", 12);
1968 vnc_flush(vs);
1969 vnc_read_when(vs, protocol_version, 12);
1970 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1971 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1972 vs->has_resize = 0;
1973 vs->has_hextile = 0;
1974 vs->ds->dpy_copy = NULL;
1975 vnc_update_client(vs);
1978 static void vnc_listen_read(void *opaque)
1980 VncState *vs = opaque;
1981 struct sockaddr_in addr;
1982 socklen_t addrlen = sizeof(addr);
1984 /* Catch-up */
1985 vga_hw_update();
1987 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1988 if (vs->csock != -1) {
1989 vnc_connect(vs);
1993 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1995 void vnc_display_init(DisplayState *ds)
1997 VncState *vs;
1999 vs = qemu_mallocz(sizeof(VncState));
2000 if (!vs)
2001 exit(1);
2003 ds->opaque = vs;
2004 ds->idle = 1;
2005 vnc_state = vs;
2006 vs->display = NULL;
2007 vs->password = NULL;
2009 vs->lsock = -1;
2010 vs->csock = -1;
2011 vs->depth = 4;
2012 vs->last_x = -1;
2013 vs->last_y = -1;
2015 vs->ds = ds;
2017 if (keyboard_layout)
2018 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
2019 else
2020 vs->kbd_layout = init_keyboard_layout("en-us");
2022 if (!vs->kbd_layout)
2023 exit(1);
2025 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
2027 vs->ds->data = NULL;
2028 vs->ds->dpy_update = vnc_dpy_update;
2029 vs->ds->dpy_resize = vnc_dpy_resize;
2030 vs->ds->dpy_refresh = NULL;
2032 vnc_dpy_resize(vs->ds, 640, 400);
2035 #if CONFIG_VNC_TLS
2036 static int vnc_set_x509_credential(VncState *vs,
2037 const char *certdir,
2038 const char *filename,
2039 char **cred,
2040 int ignoreMissing)
2042 struct stat sb;
2044 if (*cred) {
2045 qemu_free(*cred);
2046 *cred = NULL;
2049 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
2050 return -1;
2052 strcpy(*cred, certdir);
2053 strcat(*cred, "/");
2054 strcat(*cred, filename);
2056 VNC_DEBUG("Check %s\n", *cred);
2057 if (stat(*cred, &sb) < 0) {
2058 qemu_free(*cred);
2059 *cred = NULL;
2060 if (ignoreMissing && errno == ENOENT)
2061 return 0;
2062 return -1;
2065 return 0;
2068 static int vnc_set_x509_credential_dir(VncState *vs,
2069 const char *certdir)
2071 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2072 goto cleanup;
2073 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2074 goto cleanup;
2075 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2076 goto cleanup;
2077 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2078 goto cleanup;
2080 return 0;
2082 cleanup:
2083 qemu_free(vs->x509cacert);
2084 qemu_free(vs->x509cacrl);
2085 qemu_free(vs->x509cert);
2086 qemu_free(vs->x509key);
2087 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2088 return -1;
2090 #endif /* CONFIG_VNC_TLS */
2092 void vnc_display_close(DisplayState *ds)
2094 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2096 if (vs->display) {
2097 qemu_free(vs->display);
2098 vs->display = NULL;
2100 if (vs->lsock != -1) {
2101 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2102 close(vs->lsock);
2103 vs->lsock = -1;
2105 if (vs->csock != -1) {
2106 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2107 closesocket(vs->csock);
2108 vs->csock = -1;
2109 buffer_reset(&vs->input);
2110 buffer_reset(&vs->output);
2111 vs->need_update = 0;
2112 #if CONFIG_VNC_TLS
2113 if (vs->tls_session) {
2114 gnutls_deinit(vs->tls_session);
2115 vs->tls_session = NULL;
2117 vs->wiremode = VNC_WIREMODE_CLEAR;
2118 #endif /* CONFIG_VNC_TLS */
2120 vs->auth = VNC_AUTH_INVALID;
2121 #if CONFIG_VNC_TLS
2122 vs->subauth = VNC_AUTH_INVALID;
2123 vs->x509verify = 0;
2124 #endif
2127 int vnc_display_password(DisplayState *ds, const char *password)
2129 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2131 if (vs->password) {
2132 qemu_free(vs->password);
2133 vs->password = NULL;
2135 if (password && password[0]) {
2136 if (!(vs->password = qemu_strdup(password)))
2137 return -1;
2140 return 0;
2143 int vnc_display_open(DisplayState *ds, const char *display)
2145 struct sockaddr *addr;
2146 struct sockaddr_in iaddr;
2147 #ifndef _WIN32
2148 struct sockaddr_un uaddr;
2149 const char *p;
2150 #endif
2151 int reuse_addr, ret;
2152 socklen_t addrlen;
2153 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2154 const char *options;
2155 int password = 0;
2156 int reverse = 0;
2157 #if CONFIG_VNC_TLS
2158 int tls = 0, x509 = 0;
2159 #endif
2161 vnc_display_close(ds);
2162 if (strcmp(display, "none") == 0)
2163 return 0;
2165 if (!(vs->display = strdup(display)))
2166 return -1;
2168 options = display;
2169 while ((options = strchr(options, ','))) {
2170 options++;
2171 if (strncmp(options, "password", 8) == 0) {
2172 password = 1; /* Require password auth */
2173 } else if (strncmp(options, "reverse", 7) == 0) {
2174 reverse = 1;
2175 #if CONFIG_VNC_TLS
2176 } else if (strncmp(options, "tls", 3) == 0) {
2177 tls = 1; /* Require TLS */
2178 } else if (strncmp(options, "x509", 4) == 0) {
2179 char *start, *end;
2180 x509 = 1; /* Require x509 certificates */
2181 if (strncmp(options, "x509verify", 10) == 0)
2182 vs->x509verify = 1; /* ...and verify client certs */
2184 /* Now check for 'x509=/some/path' postfix
2185 * and use that to setup x509 certificate/key paths */
2186 start = strchr(options, '=');
2187 end = strchr(options, ',');
2188 if (start && (!end || (start < end))) {
2189 int len = end ? end-(start+1) : strlen(start+1);
2190 char *path = qemu_malloc(len+1);
2191 strncpy(path, start+1, len);
2192 path[len] = '\0';
2193 VNC_DEBUG("Trying certificate path '%s'\n", path);
2194 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2195 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2196 qemu_free(path);
2197 qemu_free(vs->display);
2198 vs->display = NULL;
2199 return -1;
2201 qemu_free(path);
2202 } else {
2203 fprintf(stderr, "No certificate path provided\n");
2204 qemu_free(vs->display);
2205 vs->display = NULL;
2206 return -1;
2208 #endif
2212 if (password) {
2213 #if CONFIG_VNC_TLS
2214 if (tls) {
2215 vs->auth = VNC_AUTH_VENCRYPT;
2216 if (x509) {
2217 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2218 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2219 } else {
2220 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2221 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2223 } else {
2224 #endif
2225 VNC_DEBUG("Initializing VNC server with password auth\n");
2226 vs->auth = VNC_AUTH_VNC;
2227 #if CONFIG_VNC_TLS
2228 vs->subauth = VNC_AUTH_INVALID;
2230 #endif
2231 } else {
2232 #if CONFIG_VNC_TLS
2233 if (tls) {
2234 vs->auth = VNC_AUTH_VENCRYPT;
2235 if (x509) {
2236 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2237 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2238 } else {
2239 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2240 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2242 } else {
2243 #endif
2244 VNC_DEBUG("Initializing VNC server with no auth\n");
2245 vs->auth = VNC_AUTH_NONE;
2246 #if CONFIG_VNC_TLS
2247 vs->subauth = VNC_AUTH_INVALID;
2249 #endif
2251 #ifndef _WIN32
2252 if (strstart(display, "unix:", &p)) {
2253 addr = (struct sockaddr *)&uaddr;
2254 addrlen = sizeof(uaddr);
2256 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2257 if (vs->lsock == -1) {
2258 fprintf(stderr, "Could not create socket\n");
2259 free(vs->display);
2260 vs->display = NULL;
2261 return -1;
2264 uaddr.sun_family = AF_UNIX;
2265 memset(uaddr.sun_path, 0, 108);
2266 snprintf(uaddr.sun_path, 108, "%s", p);
2268 if (!reverse) {
2269 unlink(uaddr.sun_path);
2271 } else
2272 #endif
2274 addr = (struct sockaddr *)&iaddr;
2275 addrlen = sizeof(iaddr);
2277 if (parse_host_port(&iaddr, display) < 0) {
2278 fprintf(stderr, "Could not parse VNC address\n");
2279 free(vs->display);
2280 vs->display = NULL;
2281 return -1;
2284 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900));
2286 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2287 if (vs->lsock == -1) {
2288 fprintf(stderr, "Could not create socket\n");
2289 free(vs->display);
2290 vs->display = NULL;
2291 return -1;
2294 reuse_addr = 1;
2295 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2296 (const char *)&reuse_addr, sizeof(reuse_addr));
2297 if (ret == -1) {
2298 fprintf(stderr, "setsockopt() failed\n");
2299 close(vs->lsock);
2300 vs->lsock = -1;
2301 free(vs->display);
2302 vs->display = NULL;
2303 return -1;
2307 if (reverse) {
2308 if (connect(vs->lsock, addr, addrlen) == -1) {
2309 fprintf(stderr, "Connection to VNC client failed\n");
2310 close(vs->lsock);
2311 vs->lsock = -1;
2312 free(vs->display);
2313 vs->display = NULL;
2314 return -1;
2315 } else {
2316 vs->csock = vs->lsock;
2317 vs->lsock = -1;
2318 vnc_connect(vs);
2319 return 0;
2323 if (bind(vs->lsock, addr, addrlen) == -1) {
2324 fprintf(stderr, "bind() failed\n");
2325 close(vs->lsock);
2326 vs->lsock = -1;
2327 free(vs->display);
2328 vs->display = NULL;
2329 return -1;
2332 if (listen(vs->lsock, 1) == -1) {
2333 fprintf(stderr, "listen() failed\n");
2334 close(vs->lsock);
2335 vs->lsock = -1;
2336 free(vs->display);
2337 vs->display = NULL;
2338 return -1;
2341 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);