Change the way video graphics adapter is selected
[qemu/mini2440.git] / vnc.c
blob266460ff5dfe2e743a97aeafa2af197f17a78733
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
26 #include "qemu-common.h"
27 #include "console.h"
28 #include "sysemu.h"
29 #include "qemu_socket.h"
30 #include "qemu-timer.h"
32 #define VNC_REFRESH_INTERVAL (1000 / 30)
34 #include "vnc_keysym.h"
35 #include "keymaps.c"
36 #include "d3des.h"
38 #ifdef CONFIG_VNC_TLS
39 #include <gnutls/gnutls.h>
40 #include <gnutls/x509.h>
41 #endif /* CONFIG_VNC_TLS */
43 // #define _VNC_DEBUG 1
45 #ifdef _VNC_DEBUG
46 #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
48 #if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
49 /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
50 static void vnc_debug_gnutls_log(int level, const char* str) {
51 VNC_DEBUG("%d %s", level, str);
53 #endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
54 #else
55 #define VNC_DEBUG(fmt, ...) do { } while (0)
56 #endif
59 typedef struct Buffer
61 size_t capacity;
62 size_t offset;
63 uint8_t *buffer;
64 } Buffer;
66 typedef struct VncState VncState;
68 typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
70 typedef void VncWritePixels(VncState *vs, void *data, int size);
72 typedef void VncSendHextileTile(VncState *vs,
73 int x, int y, int w, int h,
74 void *last_bg,
75 void *last_fg,
76 int *has_bg, int *has_fg);
78 #define VNC_MAX_WIDTH 2048
79 #define VNC_MAX_HEIGHT 2048
80 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
82 #define VNC_AUTH_CHALLENGE_SIZE 16
84 enum {
85 VNC_AUTH_INVALID = 0,
86 VNC_AUTH_NONE = 1,
87 VNC_AUTH_VNC = 2,
88 VNC_AUTH_RA2 = 5,
89 VNC_AUTH_RA2NE = 6,
90 VNC_AUTH_TIGHT = 16,
91 VNC_AUTH_ULTRA = 17,
92 VNC_AUTH_TLS = 18,
93 VNC_AUTH_VENCRYPT = 19
96 #ifdef CONFIG_VNC_TLS
97 enum {
98 VNC_WIREMODE_CLEAR,
99 VNC_WIREMODE_TLS,
102 enum {
103 VNC_AUTH_VENCRYPT_PLAIN = 256,
104 VNC_AUTH_VENCRYPT_TLSNONE = 257,
105 VNC_AUTH_VENCRYPT_TLSVNC = 258,
106 VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
107 VNC_AUTH_VENCRYPT_X509NONE = 260,
108 VNC_AUTH_VENCRYPT_X509VNC = 261,
109 VNC_AUTH_VENCRYPT_X509PLAIN = 262,
112 #define X509_CA_CERT_FILE "ca-cert.pem"
113 #define X509_CA_CRL_FILE "ca-crl.pem"
114 #define X509_SERVER_KEY_FILE "server-key.pem"
115 #define X509_SERVER_CERT_FILE "server-cert.pem"
117 #endif /* CONFIG_VNC_TLS */
119 struct VncState
121 QEMUTimer *timer;
122 int lsock;
123 int csock;
124 DisplayState *ds;
125 int need_update;
126 int width;
127 int height;
128 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
129 char *old_data;
130 int depth; /* internal VNC frame buffer byte per pixel */
131 int has_resize;
132 int has_hextile;
133 int has_pointer_type_change;
134 int has_WMVi;
135 int absolute;
136 int last_x;
137 int last_y;
139 int major;
140 int minor;
142 char *display;
143 char *password;
144 int auth;
145 #ifdef CONFIG_VNC_TLS
146 int subauth;
147 int x509verify;
149 char *x509cacert;
150 char *x509cacrl;
151 char *x509cert;
152 char *x509key;
153 #endif
154 char challenge[VNC_AUTH_CHALLENGE_SIZE];
156 #ifdef CONFIG_VNC_TLS
157 int wiremode;
158 gnutls_session_t tls_session;
159 #endif
161 Buffer output;
162 Buffer input;
163 kbd_layout_t *kbd_layout;
164 /* current output mode information */
165 VncWritePixels *write_pixels;
166 VncSendHextileTile *send_hextile_tile;
167 int pix_bpp, pix_big_endian;
168 int client_red_shift, client_red_max, server_red_shift, server_red_max;
169 int client_green_shift, client_green_max, server_green_shift, server_green_max;
170 int client_blue_shift, client_blue_max, server_blue_shift, server_blue_max;
172 VncReadEvent *read_handler;
173 size_t read_handler_expect;
174 /* input */
175 uint8_t modifiers_state[256];
178 static VncState *vnc_state; /* needed for info vnc */
180 void do_info_vnc(void)
182 if (vnc_state == NULL)
183 term_printf("VNC server disabled\n");
184 else {
185 term_printf("VNC server active on: ");
186 term_print_filename(vnc_state->display);
187 term_printf("\n");
189 if (vnc_state->csock == -1)
190 term_printf("No client connected\n");
191 else
192 term_printf("Client connected\n");
196 /* TODO
197 1) Get the queue working for IO.
198 2) there is some weirdness when using the -S option (the screen is grey
199 and not totally invalidated
200 3) resolutions > 1024
203 static void vnc_write(VncState *vs, const void *data, size_t len);
204 static void vnc_write_u32(VncState *vs, uint32_t value);
205 static void vnc_write_s32(VncState *vs, int32_t value);
206 static void vnc_write_u16(VncState *vs, uint16_t value);
207 static void vnc_write_u8(VncState *vs, uint8_t value);
208 static void vnc_flush(VncState *vs);
209 static void vnc_update_client(void *opaque);
210 static void vnc_client_read(void *opaque);
212 static void vnc_colordepth(DisplayState *ds, int depth);
214 static inline void vnc_set_bit(uint32_t *d, int k)
216 d[k >> 5] |= 1 << (k & 0x1f);
219 static inline void vnc_clear_bit(uint32_t *d, int k)
221 d[k >> 5] &= ~(1 << (k & 0x1f));
224 static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
226 int j;
228 j = 0;
229 while (n >= 32) {
230 d[j++] = -1;
231 n -= 32;
233 if (n > 0)
234 d[j++] = (1 << n) - 1;
235 while (j < nb_words)
236 d[j++] = 0;
239 static inline int vnc_get_bit(const uint32_t *d, int k)
241 return (d[k >> 5] >> (k & 0x1f)) & 1;
244 static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
245 int nb_words)
247 int i;
248 for(i = 0; i < nb_words; i++) {
249 if ((d1[i] & d2[i]) != 0)
250 return 1;
252 return 0;
255 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
257 VncState *vs = ds->opaque;
258 int i;
260 h += y;
262 /* round x down to ensure the loop only spans one 16-pixel block per,
263 iteration. otherwise, if (x % 16) != 0, the last iteration may span
264 two 16-pixel blocks but we only mark the first as dirty
266 w += (x % 16);
267 x -= (x % 16);
269 x = MIN(x, vs->width);
270 y = MIN(y, vs->height);
271 w = MIN(x + w, vs->width) - x;
272 h = MIN(h, vs->height);
274 for (; y < h; y++)
275 for (i = 0; i < w; i += 16)
276 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
279 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
280 int32_t encoding)
282 vnc_write_u16(vs, x);
283 vnc_write_u16(vs, y);
284 vnc_write_u16(vs, w);
285 vnc_write_u16(vs, h);
287 vnc_write_s32(vs, encoding);
290 static void vnc_dpy_resize(DisplayState *ds, int w, int h)
292 int size_changed;
293 VncState *vs = ds->opaque;
295 ds->data = qemu_realloc(ds->data, w * h * vs->depth);
296 vs->old_data = qemu_realloc(vs->old_data, w * h * vs->depth);
298 if (ds->data == NULL || vs->old_data == NULL) {
299 fprintf(stderr, "vnc: memory allocation failed\n");
300 exit(1);
303 if (ds->depth != vs->depth * 8) {
304 ds->depth = vs->depth * 8;
305 console_color_init(ds);
307 size_changed = ds->width != w || ds->height != h;
308 ds->width = w;
309 ds->height = h;
310 ds->linesize = w * vs->depth;
311 if (size_changed) {
312 vs->width = ds->width;
313 vs->height = ds->height;
314 if (vs->csock != -1 && vs->has_resize) {
315 vnc_write_u8(vs, 0); /* msg id */
316 vnc_write_u8(vs, 0);
317 vnc_write_u16(vs, 1); /* number of rects */
318 vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
319 vnc_flush(vs);
323 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
324 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
327 /* fastest code */
328 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
330 vnc_write(vs, pixels, size);
333 /* slowest but generic code. */
334 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
336 uint8_t r, g, b;
338 r = ((v >> vs->server_red_shift) & vs->server_red_max) * (vs->client_red_max + 1) /
339 (vs->server_red_max + 1);
340 g = ((v >> vs->server_green_shift) & vs->server_green_max) * (vs->client_green_max + 1) /
341 (vs->server_green_max + 1);
342 b = ((v >> vs->server_blue_shift) & vs->server_blue_max) * (vs->client_blue_max + 1) /
343 (vs->server_blue_max + 1);
344 v = (r << vs->client_red_shift) |
345 (g << vs->client_green_shift) |
346 (b << vs->client_blue_shift);
347 switch(vs->pix_bpp) {
348 case 1:
349 buf[0] = v;
350 break;
351 case 2:
352 if (vs->pix_big_endian) {
353 buf[0] = v >> 8;
354 buf[1] = v;
355 } else {
356 buf[1] = v >> 8;
357 buf[0] = v;
359 break;
360 default:
361 case 4:
362 if (vs->pix_big_endian) {
363 buf[0] = v >> 24;
364 buf[1] = v >> 16;
365 buf[2] = v >> 8;
366 buf[3] = v;
367 } else {
368 buf[3] = v >> 24;
369 buf[2] = v >> 16;
370 buf[1] = v >> 8;
371 buf[0] = v;
373 break;
377 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
379 uint8_t buf[4];
381 if (vs->depth == 4) {
382 uint32_t *pixels = pixels1;
383 int n, i;
384 n = size >> 2;
385 for(i = 0; i < n; i++) {
386 vnc_convert_pixel(vs, buf, pixels[i]);
387 vnc_write(vs, buf, vs->pix_bpp);
389 } else if (vs->depth == 2) {
390 uint16_t *pixels = pixels1;
391 int n, i;
392 n = size >> 1;
393 for(i = 0; i < n; i++) {
394 vnc_convert_pixel(vs, buf, pixels[i]);
395 vnc_write(vs, buf, vs->pix_bpp);
397 } else if (vs->depth == 1) {
398 uint8_t *pixels = pixels1;
399 int n, i;
400 n = size;
401 for(i = 0; i < n; i++) {
402 vnc_convert_pixel(vs, buf, pixels[i]);
403 vnc_write(vs, buf, vs->pix_bpp);
405 } else {
406 fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
410 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
412 int i;
413 uint8_t *row;
415 vnc_framebuffer_update(vs, x, y, w, h, 0);
417 row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
418 for (i = 0; i < h; i++) {
419 vs->write_pixels(vs, row, w * vs->depth);
420 row += vs->ds->linesize;
424 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
426 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
427 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
430 #define BPP 8
431 #include "vnchextile.h"
432 #undef BPP
434 #define BPP 16
435 #include "vnchextile.h"
436 #undef BPP
438 #define BPP 32
439 #include "vnchextile.h"
440 #undef BPP
442 #define GENERIC
443 #define BPP 8
444 #include "vnchextile.h"
445 #undef BPP
446 #undef GENERIC
448 #define GENERIC
449 #define BPP 16
450 #include "vnchextile.h"
451 #undef BPP
452 #undef GENERIC
454 #define GENERIC
455 #define BPP 32
456 #include "vnchextile.h"
457 #undef BPP
458 #undef GENERIC
460 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
462 int i, j;
463 int has_fg, has_bg;
464 uint8_t *last_fg, *last_bg;
466 vnc_framebuffer_update(vs, x, y, w, h, 5);
468 last_fg = (uint8_t *) malloc(vs->depth);
469 last_bg = (uint8_t *) malloc(vs->depth);
470 has_fg = has_bg = 0;
471 for (j = y; j < (y + h); j += 16) {
472 for (i = x; i < (x + w); i += 16) {
473 vs->send_hextile_tile(vs, i, j,
474 MIN(16, x + w - i), MIN(16, y + h - j),
475 last_bg, last_fg, &has_bg, &has_fg);
478 free(last_fg);
479 free(last_bg);
483 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
485 if (vs->has_hextile)
486 send_framebuffer_update_hextile(vs, x, y, w, h);
487 else
488 send_framebuffer_update_raw(vs, x, y, w, h);
491 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
493 int src, dst;
494 uint8_t *src_row;
495 uint8_t *dst_row;
496 char *old_row;
497 int y = 0;
498 int pitch = ds->linesize;
499 VncState *vs = ds->opaque;
501 vnc_update_client(vs);
503 if (dst_y > src_y) {
504 y = h - 1;
505 pitch = -pitch;
508 src = (ds->linesize * (src_y + y) + vs->depth * src_x);
509 dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
511 src_row = ds->data + src;
512 dst_row = ds->data + dst;
513 old_row = vs->old_data + dst;
515 for (y = 0; y < h; y++) {
516 memmove(old_row, src_row, w * vs->depth);
517 memmove(dst_row, src_row, w * vs->depth);
518 src_row += pitch;
519 dst_row += pitch;
520 old_row += pitch;
523 vnc_write_u8(vs, 0); /* msg id */
524 vnc_write_u8(vs, 0);
525 vnc_write_u16(vs, 1); /* number of rects */
526 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
527 vnc_write_u16(vs, src_x);
528 vnc_write_u16(vs, src_y);
529 vnc_flush(vs);
532 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
534 int h;
536 for (h = 1; h < (vs->height - y); h++) {
537 int tmp_x;
538 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
539 break;
540 for (tmp_x = last_x; tmp_x < x; tmp_x++)
541 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
544 return h;
547 static void vnc_update_client(void *opaque)
549 VncState *vs = opaque;
551 if (vs->need_update && vs->csock != -1) {
552 int y;
553 uint8_t *row;
554 char *old_row;
555 uint32_t width_mask[VNC_DIRTY_WORDS];
556 int n_rectangles;
557 int saved_offset;
558 int has_dirty = 0;
560 vga_hw_update();
562 vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
564 /* Walk through the dirty map and eliminate tiles that
565 really aren't dirty */
566 row = vs->ds->data;
567 old_row = vs->old_data;
569 for (y = 0; y < vs->height; y++) {
570 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
571 int x;
572 uint8_t *ptr;
573 char *old_ptr;
575 ptr = row;
576 old_ptr = (char*)old_row;
578 for (x = 0; x < vs->ds->width; x += 16) {
579 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
580 vnc_clear_bit(vs->dirty_row[y], (x / 16));
581 } else {
582 has_dirty = 1;
583 memcpy(old_ptr, ptr, 16 * vs->depth);
586 ptr += 16 * vs->depth;
587 old_ptr += 16 * vs->depth;
591 row += vs->ds->linesize;
592 old_row += vs->ds->linesize;
595 if (!has_dirty) {
596 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
597 return;
600 /* Count rectangles */
601 n_rectangles = 0;
602 vnc_write_u8(vs, 0); /* msg id */
603 vnc_write_u8(vs, 0);
604 saved_offset = vs->output.offset;
605 vnc_write_u16(vs, 0);
607 for (y = 0; y < vs->height; y++) {
608 int x;
609 int last_x = -1;
610 for (x = 0; x < vs->width / 16; x++) {
611 if (vnc_get_bit(vs->dirty_row[y], x)) {
612 if (last_x == -1) {
613 last_x = x;
615 vnc_clear_bit(vs->dirty_row[y], x);
616 } else {
617 if (last_x != -1) {
618 int h = find_dirty_height(vs, y, last_x, x);
619 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
620 n_rectangles++;
622 last_x = -1;
625 if (last_x != -1) {
626 int h = find_dirty_height(vs, y, last_x, x);
627 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
628 n_rectangles++;
631 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
632 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
633 vnc_flush(vs);
637 if (vs->csock != -1) {
638 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
643 static int vnc_listen_poll(void *opaque)
645 VncState *vs = opaque;
646 if (vs->csock == -1)
647 return 1;
648 return 0;
651 static void buffer_reserve(Buffer *buffer, size_t len)
653 if ((buffer->capacity - buffer->offset) < len) {
654 buffer->capacity += (len + 1024);
655 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
656 if (buffer->buffer == NULL) {
657 fprintf(stderr, "vnc: out of memory\n");
658 exit(1);
663 static int buffer_empty(Buffer *buffer)
665 return buffer->offset == 0;
668 static uint8_t *buffer_end(Buffer *buffer)
670 return buffer->buffer + buffer->offset;
673 static void buffer_reset(Buffer *buffer)
675 buffer->offset = 0;
678 static void buffer_append(Buffer *buffer, const void *data, size_t len)
680 memcpy(buffer->buffer + buffer->offset, data, len);
681 buffer->offset += len;
684 static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
686 if (ret == 0 || ret == -1) {
687 if (ret == -1) {
688 switch (last_errno) {
689 case EINTR:
690 case EAGAIN:
691 #ifdef _WIN32
692 case WSAEWOULDBLOCK:
693 #endif
694 return 0;
695 default:
696 break;
700 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
701 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
702 closesocket(vs->csock);
703 vs->csock = -1;
704 vs->ds->idle = 1;
705 buffer_reset(&vs->input);
706 buffer_reset(&vs->output);
707 vs->need_update = 0;
708 #ifdef CONFIG_VNC_TLS
709 if (vs->tls_session) {
710 gnutls_deinit(vs->tls_session);
711 vs->tls_session = NULL;
713 vs->wiremode = VNC_WIREMODE_CLEAR;
714 #endif /* CONFIG_VNC_TLS */
715 return 0;
717 return ret;
720 static void vnc_client_error(VncState *vs)
722 vnc_client_io_error(vs, -1, EINVAL);
725 static void vnc_client_write(void *opaque)
727 long ret;
728 VncState *vs = opaque;
730 #ifdef CONFIG_VNC_TLS
731 if (vs->tls_session) {
732 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
733 if (ret < 0) {
734 if (ret == GNUTLS_E_AGAIN)
735 errno = EAGAIN;
736 else
737 errno = EIO;
738 ret = -1;
740 } else
741 #endif /* CONFIG_VNC_TLS */
742 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
743 ret = vnc_client_io_error(vs, ret, socket_error());
744 if (!ret)
745 return;
747 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
748 vs->output.offset -= ret;
750 if (vs->output.offset == 0) {
751 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
755 static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
757 vs->read_handler = func;
758 vs->read_handler_expect = expecting;
761 static void vnc_client_read(void *opaque)
763 VncState *vs = opaque;
764 long ret;
766 buffer_reserve(&vs->input, 4096);
768 #ifdef CONFIG_VNC_TLS
769 if (vs->tls_session) {
770 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
771 if (ret < 0) {
772 if (ret == GNUTLS_E_AGAIN)
773 errno = EAGAIN;
774 else
775 errno = EIO;
776 ret = -1;
778 } else
779 #endif /* CONFIG_VNC_TLS */
780 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
781 ret = vnc_client_io_error(vs, ret, socket_error());
782 if (!ret)
783 return;
785 vs->input.offset += ret;
787 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
788 size_t len = vs->read_handler_expect;
789 int ret;
791 ret = vs->read_handler(vs, vs->input.buffer, len);
792 if (vs->csock == -1)
793 return;
795 if (!ret) {
796 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
797 vs->input.offset -= len;
798 } else {
799 vs->read_handler_expect = ret;
804 static void vnc_write(VncState *vs, const void *data, size_t len)
806 buffer_reserve(&vs->output, len);
808 if (buffer_empty(&vs->output)) {
809 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
812 buffer_append(&vs->output, data, len);
815 static void vnc_write_s32(VncState *vs, int32_t value)
817 vnc_write_u32(vs, *(uint32_t *)&value);
820 static void vnc_write_u32(VncState *vs, uint32_t value)
822 uint8_t buf[4];
824 buf[0] = (value >> 24) & 0xFF;
825 buf[1] = (value >> 16) & 0xFF;
826 buf[2] = (value >> 8) & 0xFF;
827 buf[3] = value & 0xFF;
829 vnc_write(vs, buf, 4);
832 static void vnc_write_u16(VncState *vs, uint16_t value)
834 uint8_t buf[2];
836 buf[0] = (value >> 8) & 0xFF;
837 buf[1] = value & 0xFF;
839 vnc_write(vs, buf, 2);
842 static void vnc_write_u8(VncState *vs, uint8_t value)
844 vnc_write(vs, (char *)&value, 1);
847 static void vnc_flush(VncState *vs)
849 if (vs->output.offset)
850 vnc_client_write(vs);
853 static uint8_t read_u8(uint8_t *data, size_t offset)
855 return data[offset];
858 static uint16_t read_u16(uint8_t *data, size_t offset)
860 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
863 static int32_t read_s32(uint8_t *data, size_t offset)
865 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
866 (data[offset + 2] << 8) | data[offset + 3]);
869 static uint32_t read_u32(uint8_t *data, size_t offset)
871 return ((data[offset] << 24) | (data[offset + 1] << 16) |
872 (data[offset + 2] << 8) | data[offset + 3]);
875 #ifdef CONFIG_VNC_TLS
876 static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
877 const void *data,
878 size_t len) {
879 struct VncState *vs = (struct VncState *)transport;
880 int ret;
882 retry:
883 ret = send(vs->csock, data, len, 0);
884 if (ret < 0) {
885 if (errno == EINTR)
886 goto retry;
887 return -1;
889 return ret;
893 static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
894 void *data,
895 size_t len) {
896 struct VncState *vs = (struct VncState *)transport;
897 int ret;
899 retry:
900 ret = recv(vs->csock, data, len, 0);
901 if (ret < 0) {
902 if (errno == EINTR)
903 goto retry;
904 return -1;
906 return ret;
908 #endif /* CONFIG_VNC_TLS */
910 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
914 static void check_pointer_type_change(VncState *vs, int absolute)
916 if (vs->has_pointer_type_change && vs->absolute != absolute) {
917 vnc_write_u8(vs, 0);
918 vnc_write_u8(vs, 0);
919 vnc_write_u16(vs, 1);
920 vnc_framebuffer_update(vs, absolute, 0,
921 vs->ds->width, vs->ds->height, -257);
922 vnc_flush(vs);
924 vs->absolute = absolute;
927 static void pointer_event(VncState *vs, int button_mask, int x, int y)
929 int buttons = 0;
930 int dz = 0;
932 if (button_mask & 0x01)
933 buttons |= MOUSE_EVENT_LBUTTON;
934 if (button_mask & 0x02)
935 buttons |= MOUSE_EVENT_MBUTTON;
936 if (button_mask & 0x04)
937 buttons |= MOUSE_EVENT_RBUTTON;
938 if (button_mask & 0x08)
939 dz = -1;
940 if (button_mask & 0x10)
941 dz = 1;
943 if (vs->absolute) {
944 kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
945 y * 0x7FFF / (vs->ds->height - 1),
946 dz, buttons);
947 } else if (vs->has_pointer_type_change) {
948 x -= 0x7FFF;
949 y -= 0x7FFF;
951 kbd_mouse_event(x, y, dz, buttons);
952 } else {
953 if (vs->last_x != -1)
954 kbd_mouse_event(x - vs->last_x,
955 y - vs->last_y,
956 dz, buttons);
957 vs->last_x = x;
958 vs->last_y = y;
961 check_pointer_type_change(vs, kbd_mouse_is_absolute());
964 static void reset_keys(VncState *vs)
966 int i;
967 for(i = 0; i < 256; i++) {
968 if (vs->modifiers_state[i]) {
969 if (i & 0x80)
970 kbd_put_keycode(0xe0);
971 kbd_put_keycode(i | 0x80);
972 vs->modifiers_state[i] = 0;
977 static void press_key(VncState *vs, int keysym)
979 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
980 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
983 static void do_key_event(VncState *vs, int down, int keycode, int sym)
985 /* QEMU console switch */
986 switch(keycode) {
987 case 0x2a: /* Left Shift */
988 case 0x36: /* Right Shift */
989 case 0x1d: /* Left CTRL */
990 case 0x9d: /* Right CTRL */
991 case 0x38: /* Left ALT */
992 case 0xb8: /* Right ALT */
993 if (down)
994 vs->modifiers_state[keycode] = 1;
995 else
996 vs->modifiers_state[keycode] = 0;
997 break;
998 case 0x02 ... 0x0a: /* '1' to '9' keys */
999 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1000 /* Reset the modifiers sent to the current console */
1001 reset_keys(vs);
1002 console_select(keycode - 0x02);
1003 return;
1005 break;
1006 case 0x3a: /* CapsLock */
1007 case 0x45: /* NumLock */
1008 if (!down)
1009 vs->modifiers_state[keycode] ^= 1;
1010 break;
1013 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
1014 /* If the numlock state needs to change then simulate an additional
1015 keypress before sending this one. This will happen if the user
1016 toggles numlock away from the VNC window.
1018 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
1019 if (!vs->modifiers_state[0x45]) {
1020 vs->modifiers_state[0x45] = 1;
1021 press_key(vs, 0xff7f);
1023 } else {
1024 if (vs->modifiers_state[0x45]) {
1025 vs->modifiers_state[0x45] = 0;
1026 press_key(vs, 0xff7f);
1031 if (is_graphic_console()) {
1032 if (keycode & 0x80)
1033 kbd_put_keycode(0xe0);
1034 if (down)
1035 kbd_put_keycode(keycode & 0x7f);
1036 else
1037 kbd_put_keycode(keycode | 0x80);
1038 } else {
1039 /* QEMU console emulation */
1040 if (down) {
1041 switch (keycode) {
1042 case 0x2a: /* Left Shift */
1043 case 0x36: /* Right Shift */
1044 case 0x1d: /* Left CTRL */
1045 case 0x9d: /* Right CTRL */
1046 case 0x38: /* Left ALT */
1047 case 0xb8: /* Right ALT */
1048 break;
1049 case 0xc8:
1050 kbd_put_keysym(QEMU_KEY_UP);
1051 break;
1052 case 0xd0:
1053 kbd_put_keysym(QEMU_KEY_DOWN);
1054 break;
1055 case 0xcb:
1056 kbd_put_keysym(QEMU_KEY_LEFT);
1057 break;
1058 case 0xcd:
1059 kbd_put_keysym(QEMU_KEY_RIGHT);
1060 break;
1061 case 0xd3:
1062 kbd_put_keysym(QEMU_KEY_DELETE);
1063 break;
1064 case 0xc7:
1065 kbd_put_keysym(QEMU_KEY_HOME);
1066 break;
1067 case 0xcf:
1068 kbd_put_keysym(QEMU_KEY_END);
1069 break;
1070 case 0xc9:
1071 kbd_put_keysym(QEMU_KEY_PAGEUP);
1072 break;
1073 case 0xd1:
1074 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1075 break;
1076 default:
1077 kbd_put_keysym(sym);
1078 break;
1084 static void key_event(VncState *vs, int down, uint32_t sym)
1086 int keycode;
1088 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1089 sym = sym - 'A' + 'a';
1091 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
1092 do_key_event(vs, down, keycode, sym);
1095 static void ext_key_event(VncState *vs, int down,
1096 uint32_t sym, uint16_t keycode)
1098 /* if the user specifies a keyboard layout, always use it */
1099 if (keyboard_layout)
1100 key_event(vs, down, sym);
1101 else
1102 do_key_event(vs, down, keycode, sym);
1105 static void framebuffer_update_request(VncState *vs, int incremental,
1106 int x_position, int y_position,
1107 int w, int h)
1109 if (x_position > vs->ds->width)
1110 x_position = vs->ds->width;
1111 if (y_position > vs->ds->height)
1112 y_position = vs->ds->height;
1113 if (x_position + w >= vs->ds->width)
1114 w = vs->ds->width - x_position;
1115 if (y_position + h >= vs->ds->height)
1116 h = vs->ds->height - y_position;
1118 int i;
1119 vs->need_update = 1;
1120 if (!incremental) {
1121 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1123 for (i = 0; i < h; i++) {
1124 vnc_set_bits(vs->dirty_row[y_position + i],
1125 (vs->ds->width / 16), VNC_DIRTY_WORDS);
1126 memset(old_row, 42, vs->ds->width * vs->depth);
1127 old_row += vs->ds->linesize;
1132 static void send_ext_key_event_ack(VncState *vs)
1134 vnc_write_u8(vs, 0);
1135 vnc_write_u8(vs, 0);
1136 vnc_write_u16(vs, 1);
1137 vnc_framebuffer_update(vs, 0, 0, vs->ds->width, vs->ds->height, -258);
1138 vnc_flush(vs);
1141 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1143 int i;
1145 vs->has_hextile = 0;
1146 vs->has_resize = 0;
1147 vs->has_pointer_type_change = 0;
1148 vs->has_WMVi = 0;
1149 vs->absolute = -1;
1150 vs->ds->dpy_copy = NULL;
1152 for (i = n_encodings - 1; i >= 0; i--) {
1153 switch (encodings[i]) {
1154 case 0: /* Raw */
1155 vs->has_hextile = 0;
1156 break;
1157 case 1: /* CopyRect */
1158 vs->ds->dpy_copy = vnc_copy;
1159 break;
1160 case 5: /* Hextile */
1161 vs->has_hextile = 1;
1162 break;
1163 case -223: /* DesktopResize */
1164 vs->has_resize = 1;
1165 break;
1166 case -257:
1167 vs->has_pointer_type_change = 1;
1168 break;
1169 case -258:
1170 send_ext_key_event_ack(vs);
1171 break;
1172 case 0x574D5669:
1173 vs->has_WMVi = 1;
1174 break;
1175 default:
1176 break;
1180 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1183 static void set_pixel_format(VncState *vs,
1184 int bits_per_pixel, int depth,
1185 int big_endian_flag, int true_color_flag,
1186 int red_max, int green_max, int blue_max,
1187 int red_shift, int green_shift, int blue_shift)
1189 int host_big_endian_flag;
1191 #ifdef WORDS_BIGENDIAN
1192 host_big_endian_flag = 1;
1193 #else
1194 host_big_endian_flag = 0;
1195 #endif
1196 if (!true_color_flag) {
1197 fail:
1198 vnc_client_error(vs);
1199 return;
1201 if (bits_per_pixel == 32 &&
1202 bits_per_pixel == vs->depth * 8 &&
1203 host_big_endian_flag == big_endian_flag &&
1204 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1205 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1206 vs->depth = 4;
1207 vs->write_pixels = vnc_write_pixels_copy;
1208 vs->send_hextile_tile = send_hextile_tile_32;
1209 } else
1210 if (bits_per_pixel == 16 &&
1211 bits_per_pixel == vs->depth * 8 &&
1212 host_big_endian_flag == big_endian_flag &&
1213 red_max == 31 && green_max == 63 && blue_max == 31 &&
1214 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1215 vs->depth = 2;
1216 vs->write_pixels = vnc_write_pixels_copy;
1217 vs->send_hextile_tile = send_hextile_tile_16;
1218 } else
1219 if (bits_per_pixel == 8 &&
1220 bits_per_pixel == vs->depth * 8 &&
1221 red_max == 7 && green_max == 7 && blue_max == 3 &&
1222 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1223 vs->depth = 1;
1224 vs->write_pixels = vnc_write_pixels_copy;
1225 vs->send_hextile_tile = send_hextile_tile_8;
1226 } else
1228 /* generic and slower case */
1229 if (bits_per_pixel != 8 &&
1230 bits_per_pixel != 16 &&
1231 bits_per_pixel != 32)
1232 goto fail;
1233 if (vs->depth == 4) {
1234 vs->send_hextile_tile = send_hextile_tile_generic_32;
1235 } else if (vs->depth == 2) {
1236 vs->send_hextile_tile = send_hextile_tile_generic_16;
1237 } else {
1238 vs->send_hextile_tile = send_hextile_tile_generic_8;
1241 vs->pix_big_endian = big_endian_flag;
1242 vs->write_pixels = vnc_write_pixels_generic;
1245 vs->client_red_shift = red_shift;
1246 vs->client_red_max = red_max;
1247 vs->client_green_shift = green_shift;
1248 vs->client_green_max = green_max;
1249 vs->client_blue_shift = blue_shift;
1250 vs->client_blue_max = blue_max;
1251 vs->pix_bpp = bits_per_pixel / 8;
1253 vga_hw_invalidate();
1254 vga_hw_update();
1257 static void pixel_format_message (VncState *vs) {
1258 char pad[3] = { 0, 0, 0 };
1260 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1261 if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */
1262 else vnc_write_u8(vs, vs->depth * 8); /* depth */
1264 #ifdef WORDS_BIGENDIAN
1265 vnc_write_u8(vs, 1); /* big-endian-flag */
1266 #else
1267 vnc_write_u8(vs, 0); /* big-endian-flag */
1268 #endif
1269 vnc_write_u8(vs, 1); /* true-color-flag */
1270 if (vs->depth == 4) {
1271 vnc_write_u16(vs, 0xFF); /* red-max */
1272 vnc_write_u16(vs, 0xFF); /* green-max */
1273 vnc_write_u16(vs, 0xFF); /* blue-max */
1274 vnc_write_u8(vs, 16); /* red-shift */
1275 vnc_write_u8(vs, 8); /* green-shift */
1276 vnc_write_u8(vs, 0); /* blue-shift */
1277 vs->send_hextile_tile = send_hextile_tile_32;
1278 } else if (vs->depth == 2) {
1279 vnc_write_u16(vs, 31); /* red-max */
1280 vnc_write_u16(vs, 63); /* green-max */
1281 vnc_write_u16(vs, 31); /* blue-max */
1282 vnc_write_u8(vs, 11); /* red-shift */
1283 vnc_write_u8(vs, 5); /* green-shift */
1284 vnc_write_u8(vs, 0); /* blue-shift */
1285 vs->send_hextile_tile = send_hextile_tile_16;
1286 } else if (vs->depth == 1) {
1287 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1288 vnc_write_u16(vs, 7); /* red-max */
1289 vnc_write_u16(vs, 7); /* green-max */
1290 vnc_write_u16(vs, 3); /* blue-max */
1291 vnc_write_u8(vs, 5); /* red-shift */
1292 vnc_write_u8(vs, 2); /* green-shift */
1293 vnc_write_u8(vs, 0); /* blue-shift */
1294 vs->send_hextile_tile = send_hextile_tile_8;
1296 vs->client_red_max = vs->server_red_max;
1297 vs->client_green_max = vs->server_green_max;
1298 vs->client_blue_max = vs->server_blue_max;
1299 vs->client_red_shift = vs->server_red_shift;
1300 vs->client_green_shift = vs->server_green_shift;
1301 vs->client_blue_shift = vs->server_blue_shift;
1302 vs->pix_bpp = vs->depth * 8;
1303 vs->write_pixels = vnc_write_pixels_copy;
1305 vnc_write(vs, pad, 3); /* padding */
1308 static void vnc_colordepth(DisplayState *ds, int depth)
1310 int host_big_endian_flag;
1311 struct VncState *vs = ds->opaque;
1313 switch (depth) {
1314 case 24:
1315 if (ds->depth == 32) return;
1316 depth = 32;
1317 break;
1318 case 15:
1319 case 8:
1320 case 0:
1321 return;
1322 default:
1323 break;
1326 #ifdef WORDS_BIGENDIAN
1327 host_big_endian_flag = 1;
1328 #else
1329 host_big_endian_flag = 0;
1330 #endif
1332 switch (depth) {
1333 case 8:
1334 vs->depth = depth / 8;
1335 vs->server_red_max = 7;
1336 vs->server_green_max = 7;
1337 vs->server_blue_max = 3;
1338 vs->server_red_shift = 5;
1339 vs->server_green_shift = 2;
1340 vs->server_blue_shift = 0;
1341 break;
1342 case 16:
1343 vs->depth = depth / 8;
1344 vs->server_red_max = 31;
1345 vs->server_green_max = 63;
1346 vs->server_blue_max = 31;
1347 vs->server_red_shift = 11;
1348 vs->server_green_shift = 5;
1349 vs->server_blue_shift = 0;
1350 break;
1351 case 32:
1352 vs->depth = 4;
1353 vs->server_red_max = 255;
1354 vs->server_green_max = 255;
1355 vs->server_blue_max = 255;
1356 vs->server_red_shift = 16;
1357 vs->server_green_shift = 8;
1358 vs->server_blue_shift = 0;
1359 break;
1360 default:
1361 return;
1364 if (vs->csock != -1 && vs->has_WMVi) {
1365 /* Sending a WMVi message to notify the client*/
1366 vnc_write_u8(vs, 0); /* msg id */
1367 vnc_write_u8(vs, 0);
1368 vnc_write_u16(vs, 1); /* number of rects */
1369 vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
1370 pixel_format_message(vs);
1371 vnc_flush(vs);
1372 } else {
1373 if (vs->pix_bpp == 4 && vs->depth == 4 &&
1374 host_big_endian_flag == vs->pix_big_endian &&
1375 vs->client_red_max == 0xff && vs->client_green_max == 0xff && vs->client_blue_max == 0xff &&
1376 vs->client_red_shift == 16 && vs->client_green_shift == 8 && vs->client_blue_shift == 0) {
1377 vs->write_pixels = vnc_write_pixels_copy;
1378 vs->send_hextile_tile = send_hextile_tile_32;
1379 } else if (vs->pix_bpp == 2 && vs->depth == 2 &&
1380 host_big_endian_flag == vs->pix_big_endian &&
1381 vs->client_red_max == 31 && vs->client_green_max == 63 && vs->client_blue_max == 31 &&
1382 vs->client_red_shift == 11 && vs->client_green_shift == 5 && vs->client_blue_shift == 0) {
1383 vs->write_pixels = vnc_write_pixels_copy;
1384 vs->send_hextile_tile = send_hextile_tile_16;
1385 } else if (vs->pix_bpp == 1 && vs->depth == 1 &&
1386 host_big_endian_flag == vs->pix_big_endian &&
1387 vs->client_red_max == 7 && vs->client_green_max == 7 && vs->client_blue_max == 3 &&
1388 vs->client_red_shift == 5 && vs->client_green_shift == 2 && vs->client_blue_shift == 0) {
1389 vs->write_pixels = vnc_write_pixels_copy;
1390 vs->send_hextile_tile = send_hextile_tile_8;
1391 } else {
1392 if (vs->depth == 4) {
1393 vs->send_hextile_tile = send_hextile_tile_generic_32;
1394 } else if (vs->depth == 2) {
1395 vs->send_hextile_tile = send_hextile_tile_generic_16;
1396 } else {
1397 vs->send_hextile_tile = send_hextile_tile_generic_8;
1399 vs->write_pixels = vnc_write_pixels_generic;
1404 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1406 int i;
1407 uint16_t limit;
1409 switch (data[0]) {
1410 case 0:
1411 if (len == 1)
1412 return 20;
1414 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1415 read_u8(data, 6), read_u8(data, 7),
1416 read_u16(data, 8), read_u16(data, 10),
1417 read_u16(data, 12), read_u8(data, 14),
1418 read_u8(data, 15), read_u8(data, 16));
1419 break;
1420 case 2:
1421 if (len == 1)
1422 return 4;
1424 if (len == 4)
1425 return 4 + (read_u16(data, 2) * 4);
1427 limit = read_u16(data, 2);
1428 for (i = 0; i < limit; i++) {
1429 int32_t val = read_s32(data, 4 + (i * 4));
1430 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1433 set_encodings(vs, (int32_t *)(data + 4), limit);
1434 break;
1435 case 3:
1436 if (len == 1)
1437 return 10;
1439 framebuffer_update_request(vs,
1440 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1441 read_u16(data, 6), read_u16(data, 8));
1442 break;
1443 case 4:
1444 if (len == 1)
1445 return 8;
1447 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1448 break;
1449 case 5:
1450 if (len == 1)
1451 return 6;
1453 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1454 break;
1455 case 6:
1456 if (len == 1)
1457 return 8;
1459 if (len == 8) {
1460 uint32_t dlen = read_u32(data, 4);
1461 if (dlen > 0)
1462 return 8 + dlen;
1465 client_cut_text(vs, read_u32(data, 4), data + 8);
1466 break;
1467 case 255:
1468 if (len == 1)
1469 return 2;
1471 switch (read_u8(data, 1)) {
1472 case 0:
1473 if (len == 2)
1474 return 12;
1476 ext_key_event(vs, read_u16(data, 2),
1477 read_u32(data, 4), read_u32(data, 8));
1478 break;
1479 default:
1480 printf("Msg: %d\n", read_u16(data, 0));
1481 vnc_client_error(vs);
1482 break;
1484 break;
1485 default:
1486 printf("Msg: %d\n", data[0]);
1487 vnc_client_error(vs);
1488 break;
1491 vnc_read_when(vs, protocol_client_msg, 1);
1492 return 0;
1495 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1497 char buf[1024];
1498 int size;
1500 vs->width = vs->ds->width;
1501 vs->height = vs->ds->height;
1502 vnc_write_u16(vs, vs->ds->width);
1503 vnc_write_u16(vs, vs->ds->height);
1505 pixel_format_message(vs);
1507 if (qemu_name)
1508 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1509 else
1510 size = snprintf(buf, sizeof(buf), "QEMU");
1512 vnc_write_u32(vs, size);
1513 vnc_write(vs, buf, size);
1514 vnc_flush(vs);
1516 vnc_read_when(vs, protocol_client_msg, 1);
1518 return 0;
1521 static void make_challenge(VncState *vs)
1523 int i;
1525 srand(time(NULL)+getpid()+getpid()*987654+rand());
1527 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1528 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1531 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1533 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1534 int i, j, pwlen;
1535 unsigned char key[8];
1537 if (!vs->password || !vs->password[0]) {
1538 VNC_DEBUG("No password configured on server");
1539 vnc_write_u32(vs, 1); /* Reject auth */
1540 if (vs->minor >= 8) {
1541 static const char err[] = "Authentication failed";
1542 vnc_write_u32(vs, sizeof(err));
1543 vnc_write(vs, err, sizeof(err));
1545 vnc_flush(vs);
1546 vnc_client_error(vs);
1547 return 0;
1550 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1552 /* Calculate the expected challenge response */
1553 pwlen = strlen(vs->password);
1554 for (i=0; i<sizeof(key); i++)
1555 key[i] = i<pwlen ? vs->password[i] : 0;
1556 deskey(key, EN0);
1557 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1558 des(response+j, response+j);
1560 /* Compare expected vs actual challenge response */
1561 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1562 VNC_DEBUG("Client challenge reponse did not match\n");
1563 vnc_write_u32(vs, 1); /* Reject auth */
1564 if (vs->minor >= 8) {
1565 static const char err[] = "Authentication failed";
1566 vnc_write_u32(vs, sizeof(err));
1567 vnc_write(vs, err, sizeof(err));
1569 vnc_flush(vs);
1570 vnc_client_error(vs);
1571 } else {
1572 VNC_DEBUG("Accepting VNC challenge response\n");
1573 vnc_write_u32(vs, 0); /* Accept auth */
1574 vnc_flush(vs);
1576 vnc_read_when(vs, protocol_client_init, 1);
1578 return 0;
1581 static int start_auth_vnc(VncState *vs)
1583 make_challenge(vs);
1584 /* Send client a 'random' challenge */
1585 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1586 vnc_flush(vs);
1588 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1589 return 0;
1593 #ifdef CONFIG_VNC_TLS
1594 #define DH_BITS 1024
1595 static gnutls_dh_params_t dh_params;
1597 static int vnc_tls_initialize(void)
1599 static int tlsinitialized = 0;
1601 if (tlsinitialized)
1602 return 1;
1604 if (gnutls_global_init () < 0)
1605 return 0;
1607 /* XXX ought to re-generate diffie-hellmen params periodically */
1608 if (gnutls_dh_params_init (&dh_params) < 0)
1609 return 0;
1610 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1611 return 0;
1613 #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
1614 gnutls_global_set_log_level(10);
1615 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1616 #endif
1618 tlsinitialized = 1;
1620 return 1;
1623 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1625 gnutls_anon_server_credentials anon_cred;
1626 int ret;
1628 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1629 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1630 return NULL;
1633 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1635 return anon_cred;
1639 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1641 gnutls_certificate_credentials_t x509_cred;
1642 int ret;
1644 if (!vs->x509cacert) {
1645 VNC_DEBUG("No CA x509 certificate specified\n");
1646 return NULL;
1648 if (!vs->x509cert) {
1649 VNC_DEBUG("No server x509 certificate specified\n");
1650 return NULL;
1652 if (!vs->x509key) {
1653 VNC_DEBUG("No server private key specified\n");
1654 return NULL;
1657 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1658 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1659 return NULL;
1661 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1662 vs->x509cacert,
1663 GNUTLS_X509_FMT_PEM)) < 0) {
1664 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1665 gnutls_certificate_free_credentials(x509_cred);
1666 return NULL;
1669 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1670 vs->x509cert,
1671 vs->x509key,
1672 GNUTLS_X509_FMT_PEM)) < 0) {
1673 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1674 gnutls_certificate_free_credentials(x509_cred);
1675 return NULL;
1678 if (vs->x509cacrl) {
1679 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1680 vs->x509cacrl,
1681 GNUTLS_X509_FMT_PEM)) < 0) {
1682 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1683 gnutls_certificate_free_credentials(x509_cred);
1684 return NULL;
1688 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1690 return x509_cred;
1693 static int vnc_validate_certificate(struct VncState *vs)
1695 int ret;
1696 unsigned int status;
1697 const gnutls_datum_t *certs;
1698 unsigned int nCerts, i;
1699 time_t now;
1701 VNC_DEBUG("Validating client certificate\n");
1702 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1703 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1704 return -1;
1707 if ((now = time(NULL)) == ((time_t)-1)) {
1708 return -1;
1711 if (status != 0) {
1712 if (status & GNUTLS_CERT_INVALID)
1713 VNC_DEBUG("The certificate is not trusted.\n");
1715 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1716 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1718 if (status & GNUTLS_CERT_REVOKED)
1719 VNC_DEBUG("The certificate has been revoked.\n");
1721 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1722 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1724 return -1;
1725 } else {
1726 VNC_DEBUG("Certificate is valid!\n");
1729 /* Only support x509 for now */
1730 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1731 return -1;
1733 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1734 return -1;
1736 for (i = 0 ; i < nCerts ; i++) {
1737 gnutls_x509_crt_t cert;
1738 VNC_DEBUG ("Checking certificate chain %d\n", i);
1739 if (gnutls_x509_crt_init (&cert) < 0)
1740 return -1;
1742 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1743 gnutls_x509_crt_deinit (cert);
1744 return -1;
1747 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1748 VNC_DEBUG("The certificate has expired\n");
1749 gnutls_x509_crt_deinit (cert);
1750 return -1;
1753 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1754 VNC_DEBUG("The certificate is not yet activated\n");
1755 gnutls_x509_crt_deinit (cert);
1756 return -1;
1759 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1760 VNC_DEBUG("The certificate is not yet activated\n");
1761 gnutls_x509_crt_deinit (cert);
1762 return -1;
1765 gnutls_x509_crt_deinit (cert);
1768 return 0;
1772 static int start_auth_vencrypt_subauth(VncState *vs)
1774 switch (vs->subauth) {
1775 case VNC_AUTH_VENCRYPT_TLSNONE:
1776 case VNC_AUTH_VENCRYPT_X509NONE:
1777 VNC_DEBUG("Accept TLS auth none\n");
1778 vnc_write_u32(vs, 0); /* Accept auth completion */
1779 vnc_read_when(vs, protocol_client_init, 1);
1780 break;
1782 case VNC_AUTH_VENCRYPT_TLSVNC:
1783 case VNC_AUTH_VENCRYPT_X509VNC:
1784 VNC_DEBUG("Start TLS auth VNC\n");
1785 return start_auth_vnc(vs);
1787 default: /* Should not be possible, but just in case */
1788 VNC_DEBUG("Reject auth %d\n", vs->auth);
1789 vnc_write_u8(vs, 1);
1790 if (vs->minor >= 8) {
1791 static const char err[] = "Unsupported authentication type";
1792 vnc_write_u32(vs, sizeof(err));
1793 vnc_write(vs, err, sizeof(err));
1795 vnc_client_error(vs);
1798 return 0;
1801 static void vnc_handshake_io(void *opaque);
1803 static int vnc_continue_handshake(struct VncState *vs) {
1804 int ret;
1806 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1807 if (!gnutls_error_is_fatal(ret)) {
1808 VNC_DEBUG("Handshake interrupted (blocking)\n");
1809 if (!gnutls_record_get_direction(vs->tls_session))
1810 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1811 else
1812 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1813 return 0;
1815 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1816 vnc_client_error(vs);
1817 return -1;
1820 if (vs->x509verify) {
1821 if (vnc_validate_certificate(vs) < 0) {
1822 VNC_DEBUG("Client verification failed\n");
1823 vnc_client_error(vs);
1824 return -1;
1825 } else {
1826 VNC_DEBUG("Client verification passed\n");
1830 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1831 vs->wiremode = VNC_WIREMODE_TLS;
1832 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1834 return start_auth_vencrypt_subauth(vs);
1837 static void vnc_handshake_io(void *opaque) {
1838 struct VncState *vs = (struct VncState *)opaque;
1840 VNC_DEBUG("Handshake IO continue\n");
1841 vnc_continue_handshake(vs);
1844 #define NEED_X509_AUTH(vs) \
1845 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1846 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1847 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1850 static int vnc_start_tls(struct VncState *vs) {
1851 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1852 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1853 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1854 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1856 VNC_DEBUG("Do TLS setup\n");
1857 if (vnc_tls_initialize() < 0) {
1858 VNC_DEBUG("Failed to init TLS\n");
1859 vnc_client_error(vs);
1860 return -1;
1862 if (vs->tls_session == NULL) {
1863 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1864 vnc_client_error(vs);
1865 return -1;
1868 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1869 gnutls_deinit(vs->tls_session);
1870 vs->tls_session = NULL;
1871 vnc_client_error(vs);
1872 return -1;
1875 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1876 gnutls_deinit(vs->tls_session);
1877 vs->tls_session = NULL;
1878 vnc_client_error(vs);
1879 return -1;
1882 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1883 gnutls_deinit(vs->tls_session);
1884 vs->tls_session = NULL;
1885 vnc_client_error(vs);
1886 return -1;
1889 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1890 gnutls_deinit(vs->tls_session);
1891 vs->tls_session = NULL;
1892 vnc_client_error(vs);
1893 return -1;
1896 if (NEED_X509_AUTH(vs)) {
1897 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1898 if (!x509_cred) {
1899 gnutls_deinit(vs->tls_session);
1900 vs->tls_session = NULL;
1901 vnc_client_error(vs);
1902 return -1;
1904 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1905 gnutls_deinit(vs->tls_session);
1906 vs->tls_session = NULL;
1907 gnutls_certificate_free_credentials(x509_cred);
1908 vnc_client_error(vs);
1909 return -1;
1911 if (vs->x509verify) {
1912 VNC_DEBUG("Requesting a client certificate\n");
1913 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1916 } else {
1917 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1918 if (!anon_cred) {
1919 gnutls_deinit(vs->tls_session);
1920 vs->tls_session = NULL;
1921 vnc_client_error(vs);
1922 return -1;
1924 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1925 gnutls_deinit(vs->tls_session);
1926 vs->tls_session = NULL;
1927 gnutls_anon_free_server_credentials(anon_cred);
1928 vnc_client_error(vs);
1929 return -1;
1933 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1934 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1935 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1938 VNC_DEBUG("Start TLS handshake process\n");
1939 return vnc_continue_handshake(vs);
1942 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
1944 int auth = read_u32(data, 0);
1946 if (auth != vs->subauth) {
1947 VNC_DEBUG("Rejecting auth %d\n", auth);
1948 vnc_write_u8(vs, 0); /* Reject auth */
1949 vnc_flush(vs);
1950 vnc_client_error(vs);
1951 } else {
1952 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1953 vnc_write_u8(vs, 1); /* Accept auth */
1954 vnc_flush(vs);
1956 if (vnc_start_tls(vs) < 0) {
1957 VNC_DEBUG("Failed to complete TLS\n");
1958 return 0;
1961 if (vs->wiremode == VNC_WIREMODE_TLS) {
1962 VNC_DEBUG("Starting VeNCrypt subauth\n");
1963 return start_auth_vencrypt_subauth(vs);
1964 } else {
1965 VNC_DEBUG("TLS handshake blocked\n");
1966 return 0;
1969 return 0;
1972 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
1974 if (data[0] != 0 ||
1975 data[1] != 2) {
1976 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1977 vnc_write_u8(vs, 1); /* Reject version */
1978 vnc_flush(vs);
1979 vnc_client_error(vs);
1980 } else {
1981 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1982 vnc_write_u8(vs, 0); /* Accept version */
1983 vnc_write_u8(vs, 1); /* Number of sub-auths */
1984 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1985 vnc_flush(vs);
1986 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1988 return 0;
1991 static int start_auth_vencrypt(VncState *vs)
1993 /* Send VeNCrypt version 0.2 */
1994 vnc_write_u8(vs, 0);
1995 vnc_write_u8(vs, 2);
1997 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1998 return 0;
2000 #endif /* CONFIG_VNC_TLS */
2002 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2004 /* We only advertise 1 auth scheme at a time, so client
2005 * must pick the one we sent. Verify this */
2006 if (data[0] != vs->auth) { /* Reject auth */
2007 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
2008 vnc_write_u32(vs, 1);
2009 if (vs->minor >= 8) {
2010 static const char err[] = "Authentication failed";
2011 vnc_write_u32(vs, sizeof(err));
2012 vnc_write(vs, err, sizeof(err));
2014 vnc_client_error(vs);
2015 } else { /* Accept requested auth */
2016 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2017 switch (vs->auth) {
2018 case VNC_AUTH_NONE:
2019 VNC_DEBUG("Accept auth none\n");
2020 if (vs->minor >= 8) {
2021 vnc_write_u32(vs, 0); /* Accept auth completion */
2022 vnc_flush(vs);
2024 vnc_read_when(vs, protocol_client_init, 1);
2025 break;
2027 case VNC_AUTH_VNC:
2028 VNC_DEBUG("Start VNC auth\n");
2029 return start_auth_vnc(vs);
2031 #ifdef CONFIG_VNC_TLS
2032 case VNC_AUTH_VENCRYPT:
2033 VNC_DEBUG("Accept VeNCrypt auth\n");;
2034 return start_auth_vencrypt(vs);
2035 #endif /* CONFIG_VNC_TLS */
2037 default: /* Should not be possible, but just in case */
2038 VNC_DEBUG("Reject auth %d\n", vs->auth);
2039 vnc_write_u8(vs, 1);
2040 if (vs->minor >= 8) {
2041 static const char err[] = "Authentication failed";
2042 vnc_write_u32(vs, sizeof(err));
2043 vnc_write(vs, err, sizeof(err));
2045 vnc_client_error(vs);
2048 return 0;
2051 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2053 char local[13];
2055 memcpy(local, version, 12);
2056 local[12] = 0;
2058 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2059 VNC_DEBUG("Malformed protocol version %s\n", local);
2060 vnc_client_error(vs);
2061 return 0;
2063 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2064 if (vs->major != 3 ||
2065 (vs->minor != 3 &&
2066 vs->minor != 4 &&
2067 vs->minor != 5 &&
2068 vs->minor != 7 &&
2069 vs->minor != 8)) {
2070 VNC_DEBUG("Unsupported client version\n");
2071 vnc_write_u32(vs, VNC_AUTH_INVALID);
2072 vnc_flush(vs);
2073 vnc_client_error(vs);
2074 return 0;
2076 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2077 * as equivalent to v3.3 by servers
2079 if (vs->minor == 4 || vs->minor == 5)
2080 vs->minor = 3;
2082 if (vs->minor == 3) {
2083 if (vs->auth == VNC_AUTH_NONE) {
2084 VNC_DEBUG("Tell client auth none\n");
2085 vnc_write_u32(vs, vs->auth);
2086 vnc_flush(vs);
2087 vnc_read_when(vs, protocol_client_init, 1);
2088 } else if (vs->auth == VNC_AUTH_VNC) {
2089 VNC_DEBUG("Tell client VNC auth\n");
2090 vnc_write_u32(vs, vs->auth);
2091 vnc_flush(vs);
2092 start_auth_vnc(vs);
2093 } else {
2094 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2095 vnc_write_u32(vs, VNC_AUTH_INVALID);
2096 vnc_flush(vs);
2097 vnc_client_error(vs);
2099 } else {
2100 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2101 vnc_write_u8(vs, 1); /* num auth */
2102 vnc_write_u8(vs, vs->auth);
2103 vnc_read_when(vs, protocol_client_auth, 1);
2104 vnc_flush(vs);
2107 return 0;
2110 static void vnc_connect(VncState *vs)
2112 VNC_DEBUG("New client on socket %d\n", vs->csock);
2113 vs->ds->idle = 0;
2114 socket_set_nonblock(vs->csock);
2115 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
2116 vnc_write(vs, "RFB 003.008\n", 12);
2117 vnc_flush(vs);
2118 vnc_read_when(vs, protocol_version, 12);
2119 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
2120 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
2121 vs->has_resize = 0;
2122 vs->has_hextile = 0;
2123 vs->ds->dpy_copy = NULL;
2124 vnc_update_client(vs);
2127 static void vnc_listen_read(void *opaque)
2129 VncState *vs = opaque;
2130 struct sockaddr_in addr;
2131 socklen_t addrlen = sizeof(addr);
2133 /* Catch-up */
2134 vga_hw_update();
2136 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2137 if (vs->csock != -1) {
2138 vnc_connect(vs);
2142 extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
2144 void vnc_display_init(DisplayState *ds)
2146 VncState *vs;
2148 vs = qemu_mallocz(sizeof(VncState));
2149 if (!vs)
2150 exit(1);
2152 ds->opaque = vs;
2153 ds->idle = 1;
2154 vnc_state = vs;
2155 vs->display = NULL;
2156 vs->password = NULL;
2158 vs->lsock = -1;
2159 vs->csock = -1;
2160 vs->last_x = -1;
2161 vs->last_y = -1;
2163 vs->ds = ds;
2165 if (keyboard_layout)
2166 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
2167 else
2168 vs->kbd_layout = init_keyboard_layout("en-us");
2170 if (!vs->kbd_layout)
2171 exit(1);
2173 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
2175 vs->ds->data = NULL;
2176 vs->ds->dpy_update = vnc_dpy_update;
2177 vs->ds->dpy_resize = vnc_dpy_resize;
2178 vs->ds->dpy_refresh = NULL;
2180 vnc_colordepth(vs->ds, 32);
2181 vnc_dpy_resize(vs->ds, 640, 400);
2184 #ifdef CONFIG_VNC_TLS
2185 static int vnc_set_x509_credential(VncState *vs,
2186 const char *certdir,
2187 const char *filename,
2188 char **cred,
2189 int ignoreMissing)
2191 struct stat sb;
2193 if (*cred) {
2194 qemu_free(*cred);
2195 *cred = NULL;
2198 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
2199 return -1;
2201 strcpy(*cred, certdir);
2202 strcat(*cred, "/");
2203 strcat(*cred, filename);
2205 VNC_DEBUG("Check %s\n", *cred);
2206 if (stat(*cred, &sb) < 0) {
2207 qemu_free(*cred);
2208 *cred = NULL;
2209 if (ignoreMissing && errno == ENOENT)
2210 return 0;
2211 return -1;
2214 return 0;
2217 static int vnc_set_x509_credential_dir(VncState *vs,
2218 const char *certdir)
2220 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2221 goto cleanup;
2222 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2223 goto cleanup;
2224 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2225 goto cleanup;
2226 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2227 goto cleanup;
2229 return 0;
2231 cleanup:
2232 qemu_free(vs->x509cacert);
2233 qemu_free(vs->x509cacrl);
2234 qemu_free(vs->x509cert);
2235 qemu_free(vs->x509key);
2236 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2237 return -1;
2239 #endif /* CONFIG_VNC_TLS */
2241 void vnc_display_close(DisplayState *ds)
2243 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2245 if (vs->display) {
2246 qemu_free(vs->display);
2247 vs->display = NULL;
2249 if (vs->lsock != -1) {
2250 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2251 close(vs->lsock);
2252 vs->lsock = -1;
2254 if (vs->csock != -1) {
2255 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2256 closesocket(vs->csock);
2257 vs->csock = -1;
2258 buffer_reset(&vs->input);
2259 buffer_reset(&vs->output);
2260 vs->need_update = 0;
2261 #ifdef CONFIG_VNC_TLS
2262 if (vs->tls_session) {
2263 gnutls_deinit(vs->tls_session);
2264 vs->tls_session = NULL;
2266 vs->wiremode = VNC_WIREMODE_CLEAR;
2267 #endif /* CONFIG_VNC_TLS */
2269 vs->auth = VNC_AUTH_INVALID;
2270 #ifdef CONFIG_VNC_TLS
2271 vs->subauth = VNC_AUTH_INVALID;
2272 vs->x509verify = 0;
2273 #endif
2276 int vnc_display_password(DisplayState *ds, const char *password)
2278 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2280 if (vs->password) {
2281 qemu_free(vs->password);
2282 vs->password = NULL;
2284 if (password && password[0]) {
2285 if (!(vs->password = qemu_strdup(password)))
2286 return -1;
2289 return 0;
2292 int vnc_display_open(DisplayState *ds, const char *display)
2294 struct sockaddr *addr;
2295 struct sockaddr_in iaddr;
2296 #ifndef _WIN32
2297 struct sockaddr_un uaddr;
2298 const char *p;
2299 #endif
2300 int reuse_addr, ret;
2301 socklen_t addrlen;
2302 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2303 const char *options;
2304 int password = 0;
2305 int reverse = 0;
2306 #ifdef CONFIG_VNC_TLS
2307 int tls = 0, x509 = 0;
2308 #endif
2310 vnc_display_close(ds);
2311 if (strcmp(display, "none") == 0)
2312 return 0;
2314 if (!(vs->display = strdup(display)))
2315 return -1;
2317 options = display;
2318 while ((options = strchr(options, ','))) {
2319 options++;
2320 if (strncmp(options, "password", 8) == 0) {
2321 password = 1; /* Require password auth */
2322 } else if (strncmp(options, "reverse", 7) == 0) {
2323 reverse = 1;
2324 #ifdef CONFIG_VNC_TLS
2325 } else if (strncmp(options, "tls", 3) == 0) {
2326 tls = 1; /* Require TLS */
2327 } else if (strncmp(options, "x509", 4) == 0) {
2328 char *start, *end;
2329 x509 = 1; /* Require x509 certificates */
2330 if (strncmp(options, "x509verify", 10) == 0)
2331 vs->x509verify = 1; /* ...and verify client certs */
2333 /* Now check for 'x509=/some/path' postfix
2334 * and use that to setup x509 certificate/key paths */
2335 start = strchr(options, '=');
2336 end = strchr(options, ',');
2337 if (start && (!end || (start < end))) {
2338 int len = end ? end-(start+1) : strlen(start+1);
2339 char *path = qemu_malloc(len+1);
2340 strncpy(path, start+1, len);
2341 path[len] = '\0';
2342 VNC_DEBUG("Trying certificate path '%s'\n", path);
2343 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2344 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2345 qemu_free(path);
2346 qemu_free(vs->display);
2347 vs->display = NULL;
2348 return -1;
2350 qemu_free(path);
2351 } else {
2352 fprintf(stderr, "No certificate path provided\n");
2353 qemu_free(vs->display);
2354 vs->display = NULL;
2355 return -1;
2357 #endif
2361 if (password) {
2362 #ifdef CONFIG_VNC_TLS
2363 if (tls) {
2364 vs->auth = VNC_AUTH_VENCRYPT;
2365 if (x509) {
2366 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2367 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2368 } else {
2369 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2370 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2372 } else {
2373 #endif
2374 VNC_DEBUG("Initializing VNC server with password auth\n");
2375 vs->auth = VNC_AUTH_VNC;
2376 #ifdef CONFIG_VNC_TLS
2377 vs->subauth = VNC_AUTH_INVALID;
2379 #endif
2380 } else {
2381 #ifdef CONFIG_VNC_TLS
2382 if (tls) {
2383 vs->auth = VNC_AUTH_VENCRYPT;
2384 if (x509) {
2385 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2386 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2387 } else {
2388 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2389 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2391 } else {
2392 #endif
2393 VNC_DEBUG("Initializing VNC server with no auth\n");
2394 vs->auth = VNC_AUTH_NONE;
2395 #ifdef CONFIG_VNC_TLS
2396 vs->subauth = VNC_AUTH_INVALID;
2398 #endif
2400 #ifndef _WIN32
2401 if (strstart(display, "unix:", &p)) {
2402 addr = (struct sockaddr *)&uaddr;
2403 addrlen = sizeof(uaddr);
2405 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2406 if (vs->lsock == -1) {
2407 fprintf(stderr, "Could not create socket\n");
2408 free(vs->display);
2409 vs->display = NULL;
2410 return -1;
2413 uaddr.sun_family = AF_UNIX;
2414 memset(uaddr.sun_path, 0, 108);
2415 snprintf(uaddr.sun_path, 108, "%s", p);
2417 if (!reverse) {
2418 unlink(uaddr.sun_path);
2420 } else
2421 #endif
2423 addr = (struct sockaddr *)&iaddr;
2424 addrlen = sizeof(iaddr);
2426 if (parse_host_port(&iaddr, display) < 0) {
2427 fprintf(stderr, "Could not parse VNC address\n");
2428 free(vs->display);
2429 vs->display = NULL;
2430 return -1;
2433 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900));
2435 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2436 if (vs->lsock == -1) {
2437 fprintf(stderr, "Could not create socket\n");
2438 free(vs->display);
2439 vs->display = NULL;
2440 return -1;
2443 reuse_addr = 1;
2444 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2445 (const char *)&reuse_addr, sizeof(reuse_addr));
2446 if (ret == -1) {
2447 fprintf(stderr, "setsockopt() failed\n");
2448 close(vs->lsock);
2449 vs->lsock = -1;
2450 free(vs->display);
2451 vs->display = NULL;
2452 return -1;
2456 if (reverse) {
2457 if (connect(vs->lsock, addr, addrlen) == -1) {
2458 fprintf(stderr, "Connection to VNC client failed\n");
2459 close(vs->lsock);
2460 vs->lsock = -1;
2461 free(vs->display);
2462 vs->display = NULL;
2463 return -1;
2464 } else {
2465 vs->csock = vs->lsock;
2466 vs->lsock = -1;
2467 vnc_connect(vs);
2468 return 0;
2472 if (bind(vs->lsock, addr, addrlen) == -1) {
2473 fprintf(stderr, "bind() failed\n");
2474 close(vs->lsock);
2475 vs->lsock = -1;
2476 free(vs->display);
2477 vs->display = NULL;
2478 return -1;
2481 if (listen(vs->lsock, 1) == -1) {
2482 fprintf(stderr, "listen() failed\n");
2483 close(vs->lsock);
2484 vs->lsock = -1;
2485 free(vs->display);
2486 vs->display = NULL;
2487 return -1;
2490 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);