Drop OP_CFLAGS (Avi Kivity)
[qemu/mini2440/sniper_sniper_test.git] / vnc.c
blob17ea9a20ee9e2209a227ef1b70590c9bbf5a0773
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"
31 #include "audio/audio.h"
33 #define VNC_REFRESH_INTERVAL (1000 / 30)
35 #include "vnc_keysym.h"
36 #include "keymaps.c"
37 #include "d3des.h"
39 #ifdef CONFIG_VNC_TLS
40 #include <gnutls/gnutls.h>
41 #include <gnutls/x509.h>
42 #endif /* CONFIG_VNC_TLS */
44 // #define _VNC_DEBUG 1
46 #ifdef _VNC_DEBUG
47 #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
49 #if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
50 /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
51 static void vnc_debug_gnutls_log(int level, const char* str) {
52 VNC_DEBUG("%d %s", level, str);
54 #endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
55 #else
56 #define VNC_DEBUG(fmt, ...) do { } while (0)
57 #endif
60 typedef struct Buffer
62 size_t capacity;
63 size_t offset;
64 uint8_t *buffer;
65 } Buffer;
67 typedef struct VncState VncState;
69 typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
71 typedef void VncWritePixels(VncState *vs, void *data, int size);
73 typedef void VncSendHextileTile(VncState *vs,
74 int x, int y, int w, int h,
75 void *last_bg,
76 void *last_fg,
77 int *has_bg, int *has_fg);
79 #define VNC_MAX_WIDTH 2048
80 #define VNC_MAX_HEIGHT 2048
81 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
83 #define VNC_AUTH_CHALLENGE_SIZE 16
85 enum {
86 VNC_AUTH_INVALID = 0,
87 VNC_AUTH_NONE = 1,
88 VNC_AUTH_VNC = 2,
89 VNC_AUTH_RA2 = 5,
90 VNC_AUTH_RA2NE = 6,
91 VNC_AUTH_TIGHT = 16,
92 VNC_AUTH_ULTRA = 17,
93 VNC_AUTH_TLS = 18,
94 VNC_AUTH_VENCRYPT = 19
97 #ifdef CONFIG_VNC_TLS
98 enum {
99 VNC_WIREMODE_CLEAR,
100 VNC_WIREMODE_TLS,
103 enum {
104 VNC_AUTH_VENCRYPT_PLAIN = 256,
105 VNC_AUTH_VENCRYPT_TLSNONE = 257,
106 VNC_AUTH_VENCRYPT_TLSVNC = 258,
107 VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
108 VNC_AUTH_VENCRYPT_X509NONE = 260,
109 VNC_AUTH_VENCRYPT_X509VNC = 261,
110 VNC_AUTH_VENCRYPT_X509PLAIN = 262,
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"
118 #endif /* CONFIG_VNC_TLS */
120 struct VncState
122 QEMUTimer *timer;
123 int lsock;
124 int csock;
125 DisplayState *ds;
126 int need_update;
127 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
128 char *old_data;
129 int has_resize;
130 int has_hextile;
131 int has_pointer_type_change;
132 int has_WMVi;
133 int absolute;
134 int last_x;
135 int last_y;
137 int major;
138 int minor;
140 char *display;
141 char *password;
142 int auth;
143 #ifdef CONFIG_VNC_TLS
144 int subauth;
145 int x509verify;
147 char *x509cacert;
148 char *x509cacrl;
149 char *x509cert;
150 char *x509key;
151 #endif
152 char challenge[VNC_AUTH_CHALLENGE_SIZE];
154 #ifdef CONFIG_VNC_TLS
155 int wiremode;
156 gnutls_session_t tls_session;
157 #endif
159 Buffer output;
160 Buffer input;
161 kbd_layout_t *kbd_layout;
162 /* current output mode information */
163 VncWritePixels *write_pixels;
164 VncSendHextileTile *send_hextile_tile;
165 DisplaySurface clientds, serverds;
167 CaptureVoiceOut *audio_cap;
168 struct audsettings as;
170 VncReadEvent *read_handler;
171 size_t read_handler_expect;
172 /* input */
173 uint8_t modifiers_state[256];
176 static VncState *vnc_state; /* needed for info vnc */
177 static DisplayChangeListener *dcl;
179 void do_info_vnc(void)
181 if (vnc_state == NULL || vnc_state->display == NULL)
182 term_printf("VNC server disabled\n");
183 else {
184 term_printf("VNC server active on: ");
185 term_print_filename(vnc_state->display);
186 term_printf("\n");
188 if (vnc_state->csock == -1)
189 term_printf("No client connected\n");
190 else
191 term_printf("Client connected\n");
195 /* TODO
196 1) Get the queue working for IO.
197 2) there is some weirdness when using the -S option (the screen is grey
198 and not totally invalidated
199 3) resolutions > 1024
202 static void vnc_write(VncState *vs, const void *data, size_t len);
203 static void vnc_write_u32(VncState *vs, uint32_t value);
204 static void vnc_write_s32(VncState *vs, int32_t value);
205 static void vnc_write_u16(VncState *vs, uint16_t value);
206 static void vnc_write_u8(VncState *vs, uint8_t value);
207 static void vnc_flush(VncState *vs);
208 static void vnc_update_client(void *opaque);
209 static void vnc_client_read(void *opaque);
211 static void vnc_colordepth(DisplayState *ds);
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->serverds.width);
269 y = MIN(y, vs->serverds.height);
270 w = MIN(x + w, vs->serverds.width) - x;
271 h = MIN(h, vs->serverds.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)
291 int size_changed;
292 VncState *vs = ds->opaque;
294 vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
296 if (vs->old_data == NULL) {
297 fprintf(stderr, "vnc: memory allocation failed\n");
298 exit(1);
301 if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
302 console_color_init(ds);
303 vnc_colordepth(ds);
304 size_changed = ds_get_width(ds) != vs->serverds.width ||
305 ds_get_height(ds) != vs->serverds.height;
306 vs->serverds = *(ds->surface);
307 if (size_changed) {
308 if (vs->csock != -1 && vs->has_resize) {
309 vnc_write_u8(vs, 0); /* msg id */
310 vnc_write_u8(vs, 0);
311 vnc_write_u16(vs, 1); /* number of rects */
312 vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), -223);
313 vnc_flush(vs);
317 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
318 memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
321 /* fastest code */
322 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
324 vnc_write(vs, pixels, size);
327 /* slowest but generic code. */
328 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
330 uint8_t r, g, b;
332 r = ((v >> vs->serverds.pf.rshift) & vs->serverds.pf.rmax) * (vs->clientds.pf.rmax + 1) /
333 (vs->serverds.pf.rmax + 1);
334 g = ((v >> vs->serverds.pf.gshift) & vs->serverds.pf.gmax) * (vs->clientds.pf.gmax + 1) /
335 (vs->serverds.pf.gmax + 1);
336 b = ((v >> vs->serverds.pf.bshift) & vs->serverds.pf.bmax) * (vs->clientds.pf.bmax + 1) /
337 (vs->serverds.pf.bmax + 1);
338 v = (r << vs->clientds.pf.rshift) |
339 (g << vs->clientds.pf.gshift) |
340 (b << vs->clientds.pf.bshift);
341 switch(vs->clientds.pf.bytes_per_pixel) {
342 case 1:
343 buf[0] = v;
344 break;
345 case 2:
346 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
347 buf[0] = v >> 8;
348 buf[1] = v;
349 } else {
350 buf[1] = v >> 8;
351 buf[0] = v;
353 break;
354 default:
355 case 4:
356 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
357 buf[0] = v >> 24;
358 buf[1] = v >> 16;
359 buf[2] = v >> 8;
360 buf[3] = v;
361 } else {
362 buf[3] = v >> 24;
363 buf[2] = v >> 16;
364 buf[1] = v >> 8;
365 buf[0] = v;
367 break;
371 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
373 uint8_t buf[4];
375 if (vs->serverds.pf.bytes_per_pixel == 4) {
376 uint32_t *pixels = pixels1;
377 int n, i;
378 n = size >> 2;
379 for(i = 0; i < n; i++) {
380 vnc_convert_pixel(vs, buf, pixels[i]);
381 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
383 } else if (vs->serverds.pf.bytes_per_pixel == 2) {
384 uint16_t *pixels = pixels1;
385 int n, i;
386 n = size >> 1;
387 for(i = 0; i < n; i++) {
388 vnc_convert_pixel(vs, buf, pixels[i]);
389 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
391 } else if (vs->serverds.pf.bytes_per_pixel == 1) {
392 uint8_t *pixels = pixels1;
393 int n, i;
394 n = size;
395 for(i = 0; i < n; i++) {
396 vnc_convert_pixel(vs, buf, pixels[i]);
397 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
399 } else {
400 fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
404 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
406 int i;
407 uint8_t *row;
409 vnc_framebuffer_update(vs, x, y, w, h, 0);
411 row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
412 for (i = 0; i < h; i++) {
413 vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
414 row += ds_get_linesize(vs->ds);
418 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
420 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
421 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
424 #define BPP 8
425 #include "vnchextile.h"
426 #undef BPP
428 #define BPP 16
429 #include "vnchextile.h"
430 #undef BPP
432 #define BPP 32
433 #include "vnchextile.h"
434 #undef BPP
436 #define GENERIC
437 #define BPP 8
438 #include "vnchextile.h"
439 #undef BPP
440 #undef GENERIC
442 #define GENERIC
443 #define BPP 16
444 #include "vnchextile.h"
445 #undef BPP
446 #undef GENERIC
448 #define GENERIC
449 #define BPP 32
450 #include "vnchextile.h"
451 #undef BPP
452 #undef GENERIC
454 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
456 int i, j;
457 int has_fg, has_bg;
458 uint8_t *last_fg, *last_bg;
460 vnc_framebuffer_update(vs, x, y, w, h, 5);
462 last_fg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel);
463 last_bg = (uint8_t *) malloc(vs->serverds.pf.bytes_per_pixel);
464 has_fg = has_bg = 0;
465 for (j = y; j < (y + h); j += 16) {
466 for (i = x; i < (x + w); i += 16) {
467 vs->send_hextile_tile(vs, i, j,
468 MIN(16, x + w - i), MIN(16, y + h - j),
469 last_bg, last_fg, &has_bg, &has_fg);
472 free(last_fg);
473 free(last_bg);
477 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
479 if (vs->has_hextile)
480 send_framebuffer_update_hextile(vs, x, y, w, h);
481 else
482 send_framebuffer_update_raw(vs, x, y, w, h);
485 static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
487 VncState *vs = ds->opaque;
489 vnc_update_client(vs);
491 vnc_write_u8(vs, 0); /* msg id */
492 vnc_write_u8(vs, 0);
493 vnc_write_u16(vs, 1); /* number of rects */
494 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
495 vnc_write_u16(vs, src_x);
496 vnc_write_u16(vs, src_y);
497 vnc_flush(vs);
500 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
502 int h;
504 for (h = 1; h < (vs->serverds.height - y); h++) {
505 int tmp_x;
506 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
507 break;
508 for (tmp_x = last_x; tmp_x < x; tmp_x++)
509 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
512 return h;
515 static void vnc_update_client(void *opaque)
517 VncState *vs = opaque;
519 if (vs->need_update && vs->csock != -1) {
520 int y;
521 uint8_t *row;
522 char *old_row;
523 uint32_t width_mask[VNC_DIRTY_WORDS];
524 int n_rectangles;
525 int saved_offset;
526 int has_dirty = 0;
528 vga_hw_update();
530 vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
532 /* Walk through the dirty map and eliminate tiles that
533 really aren't dirty */
534 row = ds_get_data(vs->ds);
535 old_row = vs->old_data;
537 for (y = 0; y < ds_get_height(vs->ds); y++) {
538 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
539 int x;
540 uint8_t *ptr;
541 char *old_ptr;
543 ptr = row;
544 old_ptr = (char*)old_row;
546 for (x = 0; x < ds_get_width(vs->ds); x += 16) {
547 if (memcmp(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds)) == 0) {
548 vnc_clear_bit(vs->dirty_row[y], (x / 16));
549 } else {
550 has_dirty = 1;
551 memcpy(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds));
554 ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
555 old_ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
559 row += ds_get_linesize(vs->ds);
560 old_row += ds_get_linesize(vs->ds);
563 if (!has_dirty && !vs->audio_cap) {
564 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
565 return;
568 /* Count rectangles */
569 n_rectangles = 0;
570 vnc_write_u8(vs, 0); /* msg id */
571 vnc_write_u8(vs, 0);
572 saved_offset = vs->output.offset;
573 vnc_write_u16(vs, 0);
575 for (y = 0; y < vs->serverds.height; y++) {
576 int x;
577 int last_x = -1;
578 for (x = 0; x < vs->serverds.width / 16; x++) {
579 if (vnc_get_bit(vs->dirty_row[y], x)) {
580 if (last_x == -1) {
581 last_x = x;
583 vnc_clear_bit(vs->dirty_row[y], x);
584 } else {
585 if (last_x != -1) {
586 int h = find_dirty_height(vs, y, last_x, x);
587 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
588 n_rectangles++;
590 last_x = -1;
593 if (last_x != -1) {
594 int h = find_dirty_height(vs, y, last_x, x);
595 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
596 n_rectangles++;
599 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
600 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
601 vnc_flush(vs);
605 if (vs->csock != -1) {
606 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
611 static int vnc_listen_poll(void *opaque)
613 VncState *vs = opaque;
614 if (vs->csock == -1)
615 return 1;
616 return 0;
619 static void buffer_reserve(Buffer *buffer, size_t len)
621 if ((buffer->capacity - buffer->offset) < len) {
622 buffer->capacity += (len + 1024);
623 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
624 if (buffer->buffer == NULL) {
625 fprintf(stderr, "vnc: out of memory\n");
626 exit(1);
631 static int buffer_empty(Buffer *buffer)
633 return buffer->offset == 0;
636 static uint8_t *buffer_end(Buffer *buffer)
638 return buffer->buffer + buffer->offset;
641 static void buffer_reset(Buffer *buffer)
643 buffer->offset = 0;
646 static void buffer_append(Buffer *buffer, const void *data, size_t len)
648 memcpy(buffer->buffer + buffer->offset, data, len);
649 buffer->offset += len;
652 /* audio */
653 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
655 VncState *vs = opaque;
657 switch (cmd) {
658 case AUD_CNOTIFY_DISABLE:
659 vnc_write_u8(vs, 255);
660 vnc_write_u8(vs, 1);
661 vnc_write_u16(vs, 0);
662 vnc_flush(vs);
663 break;
665 case AUD_CNOTIFY_ENABLE:
666 vnc_write_u8(vs, 255);
667 vnc_write_u8(vs, 1);
668 vnc_write_u16(vs, 1);
669 vnc_flush(vs);
670 break;
674 static void audio_capture_destroy(void *opaque)
678 static void audio_capture(void *opaque, void *buf, int size)
680 VncState *vs = opaque;
682 vnc_write_u8(vs, 255);
683 vnc_write_u8(vs, 1);
684 vnc_write_u16(vs, 2);
685 vnc_write_u32(vs, size);
686 vnc_write(vs, buf, size);
687 vnc_flush(vs);
690 static void audio_add(VncState *vs)
692 struct audio_capture_ops ops;
694 if (vs->audio_cap) {
695 term_printf ("audio already running\n");
696 return;
699 ops.notify = audio_capture_notify;
700 ops.destroy = audio_capture_destroy;
701 ops.capture = audio_capture;
703 vs->audio_cap = AUD_add_capture(NULL, &vs->as, &ops, vs);
704 if (!vs->audio_cap) {
705 term_printf ("Failed to add audio capture\n");
709 static void audio_del(VncState *vs)
711 if (vs->audio_cap) {
712 AUD_del_capture(vs->audio_cap, vs);
713 vs->audio_cap = NULL;
717 static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
719 if (ret == 0 || ret == -1) {
720 if (ret == -1) {
721 switch (last_errno) {
722 case EINTR:
723 case EAGAIN:
724 #ifdef _WIN32
725 case WSAEWOULDBLOCK:
726 #endif
727 return 0;
728 default:
729 break;
733 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
734 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
735 closesocket(vs->csock);
736 vs->csock = -1;
737 dcl->idle = 1;
738 buffer_reset(&vs->input);
739 buffer_reset(&vs->output);
740 vs->need_update = 0;
741 #ifdef CONFIG_VNC_TLS
742 if (vs->tls_session) {
743 gnutls_deinit(vs->tls_session);
744 vs->tls_session = NULL;
746 vs->wiremode = VNC_WIREMODE_CLEAR;
747 #endif /* CONFIG_VNC_TLS */
748 audio_del(vs);
749 return 0;
751 return ret;
754 static void vnc_client_error(VncState *vs)
756 vnc_client_io_error(vs, -1, EINVAL);
759 static void vnc_client_write(void *opaque)
761 long ret;
762 VncState *vs = opaque;
764 #ifdef CONFIG_VNC_TLS
765 if (vs->tls_session) {
766 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
767 if (ret < 0) {
768 if (ret == GNUTLS_E_AGAIN)
769 errno = EAGAIN;
770 else
771 errno = EIO;
772 ret = -1;
774 } else
775 #endif /* CONFIG_VNC_TLS */
776 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
777 ret = vnc_client_io_error(vs, ret, socket_error());
778 if (!ret)
779 return;
781 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
782 vs->output.offset -= ret;
784 if (vs->output.offset == 0) {
785 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
789 static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
791 vs->read_handler = func;
792 vs->read_handler_expect = expecting;
795 static void vnc_client_read(void *opaque)
797 VncState *vs = opaque;
798 long ret;
800 buffer_reserve(&vs->input, 4096);
802 #ifdef CONFIG_VNC_TLS
803 if (vs->tls_session) {
804 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
805 if (ret < 0) {
806 if (ret == GNUTLS_E_AGAIN)
807 errno = EAGAIN;
808 else
809 errno = EIO;
810 ret = -1;
812 } else
813 #endif /* CONFIG_VNC_TLS */
814 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
815 ret = vnc_client_io_error(vs, ret, socket_error());
816 if (!ret)
817 return;
819 vs->input.offset += ret;
821 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
822 size_t len = vs->read_handler_expect;
823 int ret;
825 ret = vs->read_handler(vs, vs->input.buffer, len);
826 if (vs->csock == -1)
827 return;
829 if (!ret) {
830 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
831 vs->input.offset -= len;
832 } else {
833 vs->read_handler_expect = ret;
838 static void vnc_write(VncState *vs, const void *data, size_t len)
840 buffer_reserve(&vs->output, len);
842 if (buffer_empty(&vs->output)) {
843 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
846 buffer_append(&vs->output, data, len);
849 static void vnc_write_s32(VncState *vs, int32_t value)
851 vnc_write_u32(vs, *(uint32_t *)&value);
854 static void vnc_write_u32(VncState *vs, uint32_t value)
856 uint8_t buf[4];
858 buf[0] = (value >> 24) & 0xFF;
859 buf[1] = (value >> 16) & 0xFF;
860 buf[2] = (value >> 8) & 0xFF;
861 buf[3] = value & 0xFF;
863 vnc_write(vs, buf, 4);
866 static void vnc_write_u16(VncState *vs, uint16_t value)
868 uint8_t buf[2];
870 buf[0] = (value >> 8) & 0xFF;
871 buf[1] = value & 0xFF;
873 vnc_write(vs, buf, 2);
876 static void vnc_write_u8(VncState *vs, uint8_t value)
878 vnc_write(vs, (char *)&value, 1);
881 static void vnc_flush(VncState *vs)
883 if (vs->output.offset)
884 vnc_client_write(vs);
887 static uint8_t read_u8(uint8_t *data, size_t offset)
889 return data[offset];
892 static uint16_t read_u16(uint8_t *data, size_t offset)
894 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
897 static int32_t read_s32(uint8_t *data, size_t offset)
899 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
900 (data[offset + 2] << 8) | data[offset + 3]);
903 static uint32_t read_u32(uint8_t *data, size_t offset)
905 return ((data[offset] << 24) | (data[offset + 1] << 16) |
906 (data[offset + 2] << 8) | data[offset + 3]);
909 #ifdef CONFIG_VNC_TLS
910 static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
911 const void *data,
912 size_t len) {
913 struct VncState *vs = (struct VncState *)transport;
914 int ret;
916 retry:
917 ret = send(vs->csock, data, len, 0);
918 if (ret < 0) {
919 if (errno == EINTR)
920 goto retry;
921 return -1;
923 return ret;
927 static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
928 void *data,
929 size_t len) {
930 struct VncState *vs = (struct VncState *)transport;
931 int ret;
933 retry:
934 ret = recv(vs->csock, data, len, 0);
935 if (ret < 0) {
936 if (errno == EINTR)
937 goto retry;
938 return -1;
940 return ret;
942 #endif /* CONFIG_VNC_TLS */
944 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
948 static void check_pointer_type_change(VncState *vs, int absolute)
950 if (vs->has_pointer_type_change && vs->absolute != absolute) {
951 vnc_write_u8(vs, 0);
952 vnc_write_u8(vs, 0);
953 vnc_write_u16(vs, 1);
954 vnc_framebuffer_update(vs, absolute, 0,
955 ds_get_width(vs->ds), ds_get_height(vs->ds), -257);
956 vnc_flush(vs);
958 vs->absolute = absolute;
961 static void pointer_event(VncState *vs, int button_mask, int x, int y)
963 int buttons = 0;
964 int dz = 0;
966 if (button_mask & 0x01)
967 buttons |= MOUSE_EVENT_LBUTTON;
968 if (button_mask & 0x02)
969 buttons |= MOUSE_EVENT_MBUTTON;
970 if (button_mask & 0x04)
971 buttons |= MOUSE_EVENT_RBUTTON;
972 if (button_mask & 0x08)
973 dz = -1;
974 if (button_mask & 0x10)
975 dz = 1;
977 if (vs->absolute) {
978 kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
979 y * 0x7FFF / (ds_get_height(vs->ds) - 1),
980 dz, buttons);
981 } else if (vs->has_pointer_type_change) {
982 x -= 0x7FFF;
983 y -= 0x7FFF;
985 kbd_mouse_event(x, y, dz, buttons);
986 } else {
987 if (vs->last_x != -1)
988 kbd_mouse_event(x - vs->last_x,
989 y - vs->last_y,
990 dz, buttons);
991 vs->last_x = x;
992 vs->last_y = y;
995 check_pointer_type_change(vs, kbd_mouse_is_absolute());
998 static void reset_keys(VncState *vs)
1000 int i;
1001 for(i = 0; i < 256; i++) {
1002 if (vs->modifiers_state[i]) {
1003 if (i & 0x80)
1004 kbd_put_keycode(0xe0);
1005 kbd_put_keycode(i | 0x80);
1006 vs->modifiers_state[i] = 0;
1011 static void press_key(VncState *vs, int keysym)
1013 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
1014 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
1017 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1019 /* QEMU console switch */
1020 switch(keycode) {
1021 case 0x2a: /* Left Shift */
1022 case 0x36: /* Right Shift */
1023 case 0x1d: /* Left CTRL */
1024 case 0x9d: /* Right CTRL */
1025 case 0x38: /* Left ALT */
1026 case 0xb8: /* Right ALT */
1027 if (down)
1028 vs->modifiers_state[keycode] = 1;
1029 else
1030 vs->modifiers_state[keycode] = 0;
1031 break;
1032 case 0x02 ... 0x0a: /* '1' to '9' keys */
1033 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1034 /* Reset the modifiers sent to the current console */
1035 reset_keys(vs);
1036 console_select(keycode - 0x02);
1037 return;
1039 break;
1040 case 0x3a: /* CapsLock */
1041 case 0x45: /* NumLock */
1042 if (!down)
1043 vs->modifiers_state[keycode] ^= 1;
1044 break;
1047 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
1048 /* If the numlock state needs to change then simulate an additional
1049 keypress before sending this one. This will happen if the user
1050 toggles numlock away from the VNC window.
1052 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
1053 if (!vs->modifiers_state[0x45]) {
1054 vs->modifiers_state[0x45] = 1;
1055 press_key(vs, 0xff7f);
1057 } else {
1058 if (vs->modifiers_state[0x45]) {
1059 vs->modifiers_state[0x45] = 0;
1060 press_key(vs, 0xff7f);
1065 if (is_graphic_console()) {
1066 if (keycode & 0x80)
1067 kbd_put_keycode(0xe0);
1068 if (down)
1069 kbd_put_keycode(keycode & 0x7f);
1070 else
1071 kbd_put_keycode(keycode | 0x80);
1072 } else {
1073 /* QEMU console emulation */
1074 if (down) {
1075 switch (keycode) {
1076 case 0x2a: /* Left Shift */
1077 case 0x36: /* Right Shift */
1078 case 0x1d: /* Left CTRL */
1079 case 0x9d: /* Right CTRL */
1080 case 0x38: /* Left ALT */
1081 case 0xb8: /* Right ALT */
1082 break;
1083 case 0xc8:
1084 kbd_put_keysym(QEMU_KEY_UP);
1085 break;
1086 case 0xd0:
1087 kbd_put_keysym(QEMU_KEY_DOWN);
1088 break;
1089 case 0xcb:
1090 kbd_put_keysym(QEMU_KEY_LEFT);
1091 break;
1092 case 0xcd:
1093 kbd_put_keysym(QEMU_KEY_RIGHT);
1094 break;
1095 case 0xd3:
1096 kbd_put_keysym(QEMU_KEY_DELETE);
1097 break;
1098 case 0xc7:
1099 kbd_put_keysym(QEMU_KEY_HOME);
1100 break;
1101 case 0xcf:
1102 kbd_put_keysym(QEMU_KEY_END);
1103 break;
1104 case 0xc9:
1105 kbd_put_keysym(QEMU_KEY_PAGEUP);
1106 break;
1107 case 0xd1:
1108 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1109 break;
1110 default:
1111 kbd_put_keysym(sym);
1112 break;
1118 static void key_event(VncState *vs, int down, uint32_t sym)
1120 int keycode;
1122 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1123 sym = sym - 'A' + 'a';
1125 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
1126 do_key_event(vs, down, keycode, sym);
1129 static void ext_key_event(VncState *vs, int down,
1130 uint32_t sym, uint16_t keycode)
1132 /* if the user specifies a keyboard layout, always use it */
1133 if (keyboard_layout)
1134 key_event(vs, down, sym);
1135 else
1136 do_key_event(vs, down, keycode, sym);
1139 static void framebuffer_update_request(VncState *vs, int incremental,
1140 int x_position, int y_position,
1141 int w, int h)
1143 if (x_position > ds_get_width(vs->ds))
1144 x_position = ds_get_width(vs->ds);
1145 if (y_position > ds_get_height(vs->ds))
1146 y_position = ds_get_height(vs->ds);
1147 if (x_position + w >= ds_get_width(vs->ds))
1148 w = ds_get_width(vs->ds) - x_position;
1149 if (y_position + h >= ds_get_height(vs->ds))
1150 h = ds_get_height(vs->ds) - y_position;
1152 int i;
1153 vs->need_update = 1;
1154 if (!incremental) {
1155 char *old_row = vs->old_data + y_position * ds_get_linesize(vs->ds);
1157 for (i = 0; i < h; i++) {
1158 vnc_set_bits(vs->dirty_row[y_position + i],
1159 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1160 memset(old_row, 42, ds_get_width(vs->ds) * ds_get_bytes_per_pixel(vs->ds));
1161 old_row += ds_get_linesize(vs->ds);
1166 static void send_ext_key_event_ack(VncState *vs)
1168 vnc_write_u8(vs, 0);
1169 vnc_write_u8(vs, 0);
1170 vnc_write_u16(vs, 1);
1171 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), -258);
1172 vnc_flush(vs);
1175 static void send_ext_audio_ack(VncState *vs)
1177 vnc_write_u8(vs, 0);
1178 vnc_write_u8(vs, 0);
1179 vnc_write_u16(vs, 1);
1180 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), -259);
1181 vnc_flush(vs);
1184 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1186 int i;
1188 vs->has_hextile = 0;
1189 vs->has_resize = 0;
1190 vs->has_pointer_type_change = 0;
1191 vs->has_WMVi = 0;
1192 vs->absolute = -1;
1193 dcl->dpy_copy = NULL;
1195 for (i = n_encodings - 1; i >= 0; i--) {
1196 switch (encodings[i]) {
1197 case 0: /* Raw */
1198 vs->has_hextile = 0;
1199 break;
1200 case 1: /* CopyRect */
1201 dcl->dpy_copy = vnc_copy;
1202 break;
1203 case 5: /* Hextile */
1204 vs->has_hextile = 1;
1205 break;
1206 case -223: /* DesktopResize */
1207 vs->has_resize = 1;
1208 break;
1209 case -257:
1210 vs->has_pointer_type_change = 1;
1211 break;
1212 case -258:
1213 send_ext_key_event_ack(vs);
1214 break;
1215 case -259:
1216 send_ext_audio_ack(vs);
1217 break;
1218 case 0x574D5669:
1219 vs->has_WMVi = 1;
1220 break;
1221 default:
1222 break;
1226 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1229 static void set_pixel_conversion(VncState *vs)
1231 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1232 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1233 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1234 vs->write_pixels = vnc_write_pixels_copy;
1235 switch (vs->ds->surface->pf.bits_per_pixel) {
1236 case 8:
1237 vs->send_hextile_tile = send_hextile_tile_8;
1238 break;
1239 case 16:
1240 vs->send_hextile_tile = send_hextile_tile_16;
1241 break;
1242 case 32:
1243 vs->send_hextile_tile = send_hextile_tile_32;
1244 break;
1246 } else {
1247 vs->write_pixels = vnc_write_pixels_generic;
1248 switch (vs->ds->surface->pf.bits_per_pixel) {
1249 case 8:
1250 vs->send_hextile_tile = send_hextile_tile_generic_8;
1251 break;
1252 case 16:
1253 vs->send_hextile_tile = send_hextile_tile_generic_16;
1254 break;
1255 case 32:
1256 vs->send_hextile_tile = send_hextile_tile_generic_32;
1257 break;
1262 static void set_pixel_format(VncState *vs,
1263 int bits_per_pixel, int depth,
1264 int big_endian_flag, int true_color_flag,
1265 int red_max, int green_max, int blue_max,
1266 int red_shift, int green_shift, int blue_shift)
1268 if (!true_color_flag) {
1269 vnc_client_error(vs);
1270 return;
1273 vs->clientds = vs->serverds;
1274 vs->clientds.pf.rmax = red_max;
1275 vs->clientds.pf.rshift = red_shift;
1276 vs->clientds.pf.rmask = red_max << red_shift;
1277 vs->clientds.pf.gmax = green_max;
1278 vs->clientds.pf.gshift = green_shift;
1279 vs->clientds.pf.gmask = green_max << green_shift;
1280 vs->clientds.pf.bmax = blue_max;
1281 vs->clientds.pf.bshift = blue_shift;
1282 vs->clientds.pf.bmask = blue_max << blue_shift;
1283 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1284 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1285 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1286 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1288 set_pixel_conversion(vs);
1290 vga_hw_invalidate();
1291 vga_hw_update();
1294 static void pixel_format_message (VncState *vs) {
1295 char pad[3] = { 0, 0, 0 };
1297 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1298 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
1300 #ifdef WORDS_BIGENDIAN
1301 vnc_write_u8(vs, 1); /* big-endian-flag */
1302 #else
1303 vnc_write_u8(vs, 0); /* big-endian-flag */
1304 #endif
1305 vnc_write_u8(vs, 1); /* true-color-flag */
1306 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1307 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1308 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1309 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1310 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1311 vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
1312 if (vs->ds->surface->pf.bits_per_pixel == 32)
1313 vs->send_hextile_tile = send_hextile_tile_32;
1314 else if (vs->ds->surface->pf.bits_per_pixel == 16)
1315 vs->send_hextile_tile = send_hextile_tile_16;
1316 else if (vs->ds->surface->pf.bits_per_pixel == 8)
1317 vs->send_hextile_tile = send_hextile_tile_8;
1318 vs->clientds = *(vs->ds->surface);
1319 vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
1320 vs->write_pixels = vnc_write_pixels_copy;
1322 vnc_write(vs, pad, 3); /* padding */
1325 static void vnc_dpy_setdata(DisplayState *ds)
1327 /* We don't have to do anything */
1330 static void vnc_colordepth(DisplayState *ds)
1332 struct VncState *vs = ds->opaque;
1334 if (vs->csock != -1 && vs->has_WMVi) {
1335 /* Sending a WMVi message to notify the client*/
1336 vnc_write_u8(vs, 0); /* msg id */
1337 vnc_write_u8(vs, 0);
1338 vnc_write_u16(vs, 1); /* number of rects */
1339 vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), 0x574D5669);
1340 pixel_format_message(vs);
1341 vnc_flush(vs);
1342 } else {
1343 set_pixel_conversion(vs);
1347 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1349 int i;
1350 uint16_t limit;
1352 switch (data[0]) {
1353 case 0:
1354 if (len == 1)
1355 return 20;
1357 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1358 read_u8(data, 6), read_u8(data, 7),
1359 read_u16(data, 8), read_u16(data, 10),
1360 read_u16(data, 12), read_u8(data, 14),
1361 read_u8(data, 15), read_u8(data, 16));
1362 break;
1363 case 2:
1364 if (len == 1)
1365 return 4;
1367 if (len == 4) {
1368 limit = read_u16(data, 2);
1369 if (limit > 0)
1370 return 4 + (limit * 4);
1371 } else
1372 limit = read_u16(data, 2);
1374 for (i = 0; i < limit; i++) {
1375 int32_t val = read_s32(data, 4 + (i * 4));
1376 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1379 set_encodings(vs, (int32_t *)(data + 4), limit);
1380 break;
1381 case 3:
1382 if (len == 1)
1383 return 10;
1385 framebuffer_update_request(vs,
1386 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1387 read_u16(data, 6), read_u16(data, 8));
1388 break;
1389 case 4:
1390 if (len == 1)
1391 return 8;
1393 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1394 break;
1395 case 5:
1396 if (len == 1)
1397 return 6;
1399 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1400 break;
1401 case 6:
1402 if (len == 1)
1403 return 8;
1405 if (len == 8) {
1406 uint32_t dlen = read_u32(data, 4);
1407 if (dlen > 0)
1408 return 8 + dlen;
1411 client_cut_text(vs, read_u32(data, 4), data + 8);
1412 break;
1413 case 255:
1414 if (len == 1)
1415 return 2;
1417 switch (read_u8(data, 1)) {
1418 case 0:
1419 if (len == 2)
1420 return 12;
1422 ext_key_event(vs, read_u16(data, 2),
1423 read_u32(data, 4), read_u32(data, 8));
1424 break;
1425 case 1:
1426 if (len == 2)
1427 return 4;
1429 switch (read_u16 (data, 2)) {
1430 case 0:
1431 audio_add(vs);
1432 break;
1433 case 1:
1434 audio_del(vs);
1435 break;
1436 case 2:
1437 if (len == 4)
1438 return 10;
1439 switch (read_u8(data, 4)) {
1440 case 0: vs->as.fmt = AUD_FMT_U8; break;
1441 case 1: vs->as.fmt = AUD_FMT_S8; break;
1442 case 2: vs->as.fmt = AUD_FMT_U16; break;
1443 case 3: vs->as.fmt = AUD_FMT_S16; break;
1444 case 4: vs->as.fmt = AUD_FMT_U32; break;
1445 case 5: vs->as.fmt = AUD_FMT_S32; break;
1446 default:
1447 printf("Invalid audio format %d\n", read_u8(data, 4));
1448 vnc_client_error(vs);
1449 break;
1451 vs->as.nchannels = read_u8(data, 5);
1452 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
1453 printf("Invalid audio channel coount %d\n",
1454 read_u8(data, 5));
1455 vnc_client_error(vs);
1456 break;
1458 vs->as.freq = read_u32(data, 6);
1459 break;
1460 default:
1461 printf ("Invalid audio message %d\n", read_u8(data, 4));
1462 vnc_client_error(vs);
1463 break;
1465 break;
1467 default:
1468 printf("Msg: %d\n", read_u16(data, 0));
1469 vnc_client_error(vs);
1470 break;
1472 break;
1473 default:
1474 printf("Msg: %d\n", data[0]);
1475 vnc_client_error(vs);
1476 break;
1479 vnc_read_when(vs, protocol_client_msg, 1);
1480 return 0;
1483 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1485 char buf[1024];
1486 int size;
1488 vnc_write_u16(vs, ds_get_width(vs->ds));
1489 vnc_write_u16(vs, ds_get_height(vs->ds));
1491 pixel_format_message(vs);
1493 if (qemu_name)
1494 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1495 else
1496 size = snprintf(buf, sizeof(buf), "QEMU");
1498 vnc_write_u32(vs, size);
1499 vnc_write(vs, buf, size);
1500 vnc_flush(vs);
1502 vnc_read_when(vs, protocol_client_msg, 1);
1504 return 0;
1507 static void make_challenge(VncState *vs)
1509 int i;
1511 srand(time(NULL)+getpid()+getpid()*987654+rand());
1513 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1514 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1517 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1519 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1520 int i, j, pwlen;
1521 unsigned char key[8];
1523 if (!vs->password || !vs->password[0]) {
1524 VNC_DEBUG("No password configured on server");
1525 vnc_write_u32(vs, 1); /* Reject auth */
1526 if (vs->minor >= 8) {
1527 static const char err[] = "Authentication failed";
1528 vnc_write_u32(vs, sizeof(err));
1529 vnc_write(vs, err, sizeof(err));
1531 vnc_flush(vs);
1532 vnc_client_error(vs);
1533 return 0;
1536 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1538 /* Calculate the expected challenge response */
1539 pwlen = strlen(vs->password);
1540 for (i=0; i<sizeof(key); i++)
1541 key[i] = i<pwlen ? vs->password[i] : 0;
1542 deskey(key, EN0);
1543 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1544 des(response+j, response+j);
1546 /* Compare expected vs actual challenge response */
1547 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1548 VNC_DEBUG("Client challenge reponse did not match\n");
1549 vnc_write_u32(vs, 1); /* Reject auth */
1550 if (vs->minor >= 8) {
1551 static const char err[] = "Authentication failed";
1552 vnc_write_u32(vs, sizeof(err));
1553 vnc_write(vs, err, sizeof(err));
1555 vnc_flush(vs);
1556 vnc_client_error(vs);
1557 } else {
1558 VNC_DEBUG("Accepting VNC challenge response\n");
1559 vnc_write_u32(vs, 0); /* Accept auth */
1560 vnc_flush(vs);
1562 vnc_read_when(vs, protocol_client_init, 1);
1564 return 0;
1567 static int start_auth_vnc(VncState *vs)
1569 make_challenge(vs);
1570 /* Send client a 'random' challenge */
1571 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1572 vnc_flush(vs);
1574 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1575 return 0;
1579 #ifdef CONFIG_VNC_TLS
1580 #define DH_BITS 1024
1581 static gnutls_dh_params_t dh_params;
1583 static int vnc_tls_initialize(void)
1585 static int tlsinitialized = 0;
1587 if (tlsinitialized)
1588 return 1;
1590 if (gnutls_global_init () < 0)
1591 return 0;
1593 /* XXX ought to re-generate diffie-hellmen params periodically */
1594 if (gnutls_dh_params_init (&dh_params) < 0)
1595 return 0;
1596 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1597 return 0;
1599 #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
1600 gnutls_global_set_log_level(10);
1601 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1602 #endif
1604 tlsinitialized = 1;
1606 return 1;
1609 static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1611 gnutls_anon_server_credentials anon_cred;
1612 int ret;
1614 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1615 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1616 return NULL;
1619 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1621 return anon_cred;
1625 static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
1627 gnutls_certificate_credentials_t x509_cred;
1628 int ret;
1630 if (!vs->x509cacert) {
1631 VNC_DEBUG("No CA x509 certificate specified\n");
1632 return NULL;
1634 if (!vs->x509cert) {
1635 VNC_DEBUG("No server x509 certificate specified\n");
1636 return NULL;
1638 if (!vs->x509key) {
1639 VNC_DEBUG("No server private key specified\n");
1640 return NULL;
1643 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1644 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1645 return NULL;
1647 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1648 vs->x509cacert,
1649 GNUTLS_X509_FMT_PEM)) < 0) {
1650 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1651 gnutls_certificate_free_credentials(x509_cred);
1652 return NULL;
1655 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1656 vs->x509cert,
1657 vs->x509key,
1658 GNUTLS_X509_FMT_PEM)) < 0) {
1659 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1660 gnutls_certificate_free_credentials(x509_cred);
1661 return NULL;
1664 if (vs->x509cacrl) {
1665 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1666 vs->x509cacrl,
1667 GNUTLS_X509_FMT_PEM)) < 0) {
1668 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1669 gnutls_certificate_free_credentials(x509_cred);
1670 return NULL;
1674 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1676 return x509_cred;
1679 static int vnc_validate_certificate(struct VncState *vs)
1681 int ret;
1682 unsigned int status;
1683 const gnutls_datum_t *certs;
1684 unsigned int nCerts, i;
1685 time_t now;
1687 VNC_DEBUG("Validating client certificate\n");
1688 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1689 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1690 return -1;
1693 if ((now = time(NULL)) == ((time_t)-1)) {
1694 return -1;
1697 if (status != 0) {
1698 if (status & GNUTLS_CERT_INVALID)
1699 VNC_DEBUG("The certificate is not trusted.\n");
1701 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1702 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1704 if (status & GNUTLS_CERT_REVOKED)
1705 VNC_DEBUG("The certificate has been revoked.\n");
1707 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1708 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1710 return -1;
1711 } else {
1712 VNC_DEBUG("Certificate is valid!\n");
1715 /* Only support x509 for now */
1716 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1717 return -1;
1719 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1720 return -1;
1722 for (i = 0 ; i < nCerts ; i++) {
1723 gnutls_x509_crt_t cert;
1724 VNC_DEBUG ("Checking certificate chain %d\n", i);
1725 if (gnutls_x509_crt_init (&cert) < 0)
1726 return -1;
1728 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1729 gnutls_x509_crt_deinit (cert);
1730 return -1;
1733 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1734 VNC_DEBUG("The certificate has expired\n");
1735 gnutls_x509_crt_deinit (cert);
1736 return -1;
1739 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1740 VNC_DEBUG("The certificate is not yet activated\n");
1741 gnutls_x509_crt_deinit (cert);
1742 return -1;
1745 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1746 VNC_DEBUG("The certificate is not yet activated\n");
1747 gnutls_x509_crt_deinit (cert);
1748 return -1;
1751 gnutls_x509_crt_deinit (cert);
1754 return 0;
1758 static int start_auth_vencrypt_subauth(VncState *vs)
1760 switch (vs->subauth) {
1761 case VNC_AUTH_VENCRYPT_TLSNONE:
1762 case VNC_AUTH_VENCRYPT_X509NONE:
1763 VNC_DEBUG("Accept TLS auth none\n");
1764 vnc_write_u32(vs, 0); /* Accept auth completion */
1765 vnc_read_when(vs, protocol_client_init, 1);
1766 break;
1768 case VNC_AUTH_VENCRYPT_TLSVNC:
1769 case VNC_AUTH_VENCRYPT_X509VNC:
1770 VNC_DEBUG("Start TLS auth VNC\n");
1771 return start_auth_vnc(vs);
1773 default: /* Should not be possible, but just in case */
1774 VNC_DEBUG("Reject auth %d\n", vs->auth);
1775 vnc_write_u8(vs, 1);
1776 if (vs->minor >= 8) {
1777 static const char err[] = "Unsupported authentication type";
1778 vnc_write_u32(vs, sizeof(err));
1779 vnc_write(vs, err, sizeof(err));
1781 vnc_client_error(vs);
1784 return 0;
1787 static void vnc_handshake_io(void *opaque);
1789 static int vnc_continue_handshake(struct VncState *vs) {
1790 int ret;
1792 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1793 if (!gnutls_error_is_fatal(ret)) {
1794 VNC_DEBUG("Handshake interrupted (blocking)\n");
1795 if (!gnutls_record_get_direction(vs->tls_session))
1796 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1797 else
1798 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1799 return 0;
1801 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1802 vnc_client_error(vs);
1803 return -1;
1806 if (vs->x509verify) {
1807 if (vnc_validate_certificate(vs) < 0) {
1808 VNC_DEBUG("Client verification failed\n");
1809 vnc_client_error(vs);
1810 return -1;
1811 } else {
1812 VNC_DEBUG("Client verification passed\n");
1816 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1817 vs->wiremode = VNC_WIREMODE_TLS;
1818 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1820 return start_auth_vencrypt_subauth(vs);
1823 static void vnc_handshake_io(void *opaque) {
1824 struct VncState *vs = (struct VncState *)opaque;
1826 VNC_DEBUG("Handshake IO continue\n");
1827 vnc_continue_handshake(vs);
1830 #define NEED_X509_AUTH(vs) \
1831 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1832 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1833 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1836 static int vnc_start_tls(struct VncState *vs) {
1837 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1838 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1839 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
1840 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
1842 VNC_DEBUG("Do TLS setup\n");
1843 if (vnc_tls_initialize() < 0) {
1844 VNC_DEBUG("Failed to init TLS\n");
1845 vnc_client_error(vs);
1846 return -1;
1848 if (vs->tls_session == NULL) {
1849 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1850 vnc_client_error(vs);
1851 return -1;
1854 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1855 gnutls_deinit(vs->tls_session);
1856 vs->tls_session = NULL;
1857 vnc_client_error(vs);
1858 return -1;
1861 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
1862 gnutls_deinit(vs->tls_session);
1863 vs->tls_session = NULL;
1864 vnc_client_error(vs);
1865 return -1;
1868 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1869 gnutls_deinit(vs->tls_session);
1870 vs->tls_session = NULL;
1871 vnc_client_error(vs);
1872 return -1;
1875 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1876 gnutls_deinit(vs->tls_session);
1877 vs->tls_session = NULL;
1878 vnc_client_error(vs);
1879 return -1;
1882 if (NEED_X509_AUTH(vs)) {
1883 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
1884 if (!x509_cred) {
1885 gnutls_deinit(vs->tls_session);
1886 vs->tls_session = NULL;
1887 vnc_client_error(vs);
1888 return -1;
1890 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1891 gnutls_deinit(vs->tls_session);
1892 vs->tls_session = NULL;
1893 gnutls_certificate_free_credentials(x509_cred);
1894 vnc_client_error(vs);
1895 return -1;
1897 if (vs->x509verify) {
1898 VNC_DEBUG("Requesting a client certificate\n");
1899 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1902 } else {
1903 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1904 if (!anon_cred) {
1905 gnutls_deinit(vs->tls_session);
1906 vs->tls_session = NULL;
1907 vnc_client_error(vs);
1908 return -1;
1910 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1911 gnutls_deinit(vs->tls_session);
1912 vs->tls_session = NULL;
1913 gnutls_anon_free_server_credentials(anon_cred);
1914 vnc_client_error(vs);
1915 return -1;
1919 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1920 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1921 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1924 VNC_DEBUG("Start TLS handshake process\n");
1925 return vnc_continue_handshake(vs);
1928 static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
1930 int auth = read_u32(data, 0);
1932 if (auth != vs->subauth) {
1933 VNC_DEBUG("Rejecting auth %d\n", auth);
1934 vnc_write_u8(vs, 0); /* Reject auth */
1935 vnc_flush(vs);
1936 vnc_client_error(vs);
1937 } else {
1938 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1939 vnc_write_u8(vs, 1); /* Accept auth */
1940 vnc_flush(vs);
1942 if (vnc_start_tls(vs) < 0) {
1943 VNC_DEBUG("Failed to complete TLS\n");
1944 return 0;
1947 if (vs->wiremode == VNC_WIREMODE_TLS) {
1948 VNC_DEBUG("Starting VeNCrypt subauth\n");
1949 return start_auth_vencrypt_subauth(vs);
1950 } else {
1951 VNC_DEBUG("TLS handshake blocked\n");
1952 return 0;
1955 return 0;
1958 static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
1960 if (data[0] != 0 ||
1961 data[1] != 2) {
1962 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1963 vnc_write_u8(vs, 1); /* Reject version */
1964 vnc_flush(vs);
1965 vnc_client_error(vs);
1966 } else {
1967 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1968 vnc_write_u8(vs, 0); /* Accept version */
1969 vnc_write_u8(vs, 1); /* Number of sub-auths */
1970 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1971 vnc_flush(vs);
1972 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1974 return 0;
1977 static int start_auth_vencrypt(VncState *vs)
1979 /* Send VeNCrypt version 0.2 */
1980 vnc_write_u8(vs, 0);
1981 vnc_write_u8(vs, 2);
1983 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1984 return 0;
1986 #endif /* CONFIG_VNC_TLS */
1988 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1990 /* We only advertise 1 auth scheme at a time, so client
1991 * must pick the one we sent. Verify this */
1992 if (data[0] != vs->auth) { /* Reject auth */
1993 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1994 vnc_write_u32(vs, 1);
1995 if (vs->minor >= 8) {
1996 static const char err[] = "Authentication failed";
1997 vnc_write_u32(vs, sizeof(err));
1998 vnc_write(vs, err, sizeof(err));
2000 vnc_client_error(vs);
2001 } else { /* Accept requested auth */
2002 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
2003 switch (vs->auth) {
2004 case VNC_AUTH_NONE:
2005 VNC_DEBUG("Accept auth none\n");
2006 if (vs->minor >= 8) {
2007 vnc_write_u32(vs, 0); /* Accept auth completion */
2008 vnc_flush(vs);
2010 vnc_read_when(vs, protocol_client_init, 1);
2011 break;
2013 case VNC_AUTH_VNC:
2014 VNC_DEBUG("Start VNC auth\n");
2015 return start_auth_vnc(vs);
2017 #ifdef CONFIG_VNC_TLS
2018 case VNC_AUTH_VENCRYPT:
2019 VNC_DEBUG("Accept VeNCrypt auth\n");;
2020 return start_auth_vencrypt(vs);
2021 #endif /* CONFIG_VNC_TLS */
2023 default: /* Should not be possible, but just in case */
2024 VNC_DEBUG("Reject auth %d\n", vs->auth);
2025 vnc_write_u8(vs, 1);
2026 if (vs->minor >= 8) {
2027 static const char err[] = "Authentication failed";
2028 vnc_write_u32(vs, sizeof(err));
2029 vnc_write(vs, err, sizeof(err));
2031 vnc_client_error(vs);
2034 return 0;
2037 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2039 char local[13];
2041 memcpy(local, version, 12);
2042 local[12] = 0;
2044 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2045 VNC_DEBUG("Malformed protocol version %s\n", local);
2046 vnc_client_error(vs);
2047 return 0;
2049 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2050 if (vs->major != 3 ||
2051 (vs->minor != 3 &&
2052 vs->minor != 4 &&
2053 vs->minor != 5 &&
2054 vs->minor != 7 &&
2055 vs->minor != 8)) {
2056 VNC_DEBUG("Unsupported client version\n");
2057 vnc_write_u32(vs, VNC_AUTH_INVALID);
2058 vnc_flush(vs);
2059 vnc_client_error(vs);
2060 return 0;
2062 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2063 * as equivalent to v3.3 by servers
2065 if (vs->minor == 4 || vs->minor == 5)
2066 vs->minor = 3;
2068 if (vs->minor == 3) {
2069 if (vs->auth == VNC_AUTH_NONE) {
2070 VNC_DEBUG("Tell client auth none\n");
2071 vnc_write_u32(vs, vs->auth);
2072 vnc_flush(vs);
2073 vnc_read_when(vs, protocol_client_init, 1);
2074 } else if (vs->auth == VNC_AUTH_VNC) {
2075 VNC_DEBUG("Tell client VNC auth\n");
2076 vnc_write_u32(vs, vs->auth);
2077 vnc_flush(vs);
2078 start_auth_vnc(vs);
2079 } else {
2080 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
2081 vnc_write_u32(vs, VNC_AUTH_INVALID);
2082 vnc_flush(vs);
2083 vnc_client_error(vs);
2085 } else {
2086 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
2087 vnc_write_u8(vs, 1); /* num auth */
2088 vnc_write_u8(vs, vs->auth);
2089 vnc_read_when(vs, protocol_client_auth, 1);
2090 vnc_flush(vs);
2093 return 0;
2096 static void vnc_connect(VncState *vs)
2098 VNC_DEBUG("New client on socket %d\n", vs->csock);
2099 dcl->idle = 0;
2100 socket_set_nonblock(vs->csock);
2101 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
2102 vnc_write(vs, "RFB 003.008\n", 12);
2103 vnc_flush(vs);
2104 vnc_read_when(vs, protocol_version, 12);
2105 memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
2106 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
2107 vs->has_resize = 0;
2108 vs->has_hextile = 0;
2109 dcl->dpy_copy = NULL;
2110 vnc_update_client(vs);
2111 reset_keys(vs);
2114 static void vnc_listen_read(void *opaque)
2116 VncState *vs = opaque;
2117 struct sockaddr_in addr;
2118 socklen_t addrlen = sizeof(addr);
2120 /* Catch-up */
2121 vga_hw_update();
2123 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2124 if (vs->csock != -1) {
2125 vnc_connect(vs);
2129 void vnc_display_init(DisplayState *ds)
2131 VncState *vs;
2133 vs = qemu_mallocz(sizeof(VncState));
2134 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
2135 if (!vs || !dcl)
2136 exit(1);
2138 ds->opaque = vs;
2139 dcl->idle = 1;
2140 vnc_state = vs;
2141 vs->display = NULL;
2142 vs->password = NULL;
2144 vs->lsock = -1;
2145 vs->csock = -1;
2146 vs->last_x = -1;
2147 vs->last_y = -1;
2149 vs->ds = ds;
2151 if (keyboard_layout)
2152 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
2153 else
2154 vs->kbd_layout = init_keyboard_layout("en-us");
2156 if (!vs->kbd_layout)
2157 exit(1);
2159 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
2161 dcl->dpy_update = vnc_dpy_update;
2162 dcl->dpy_resize = vnc_dpy_resize;
2163 dcl->dpy_setdata = vnc_dpy_setdata;
2164 dcl->dpy_refresh = NULL;
2165 register_displaychangelistener(ds, dcl);
2167 vs->as.freq = 44100;
2168 vs->as.nchannels = 2;
2169 vs->as.fmt = AUD_FMT_S16;
2170 vs->as.endianness = 0;
2173 #ifdef CONFIG_VNC_TLS
2174 static int vnc_set_x509_credential(VncState *vs,
2175 const char *certdir,
2176 const char *filename,
2177 char **cred,
2178 int ignoreMissing)
2180 struct stat sb;
2182 if (*cred) {
2183 qemu_free(*cred);
2184 *cred = NULL;
2187 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
2188 return -1;
2190 strcpy(*cred, certdir);
2191 strcat(*cred, "/");
2192 strcat(*cred, filename);
2194 VNC_DEBUG("Check %s\n", *cred);
2195 if (stat(*cred, &sb) < 0) {
2196 qemu_free(*cred);
2197 *cred = NULL;
2198 if (ignoreMissing && errno == ENOENT)
2199 return 0;
2200 return -1;
2203 return 0;
2206 static int vnc_set_x509_credential_dir(VncState *vs,
2207 const char *certdir)
2209 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2210 goto cleanup;
2211 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2212 goto cleanup;
2213 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2214 goto cleanup;
2215 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2216 goto cleanup;
2218 return 0;
2220 cleanup:
2221 qemu_free(vs->x509cacert);
2222 qemu_free(vs->x509cacrl);
2223 qemu_free(vs->x509cert);
2224 qemu_free(vs->x509key);
2225 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2226 return -1;
2228 #endif /* CONFIG_VNC_TLS */
2230 void vnc_display_close(DisplayState *ds)
2232 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2234 if (vs->display) {
2235 qemu_free(vs->display);
2236 vs->display = NULL;
2238 if (vs->lsock != -1) {
2239 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2240 close(vs->lsock);
2241 vs->lsock = -1;
2243 if (vs->csock != -1) {
2244 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2245 closesocket(vs->csock);
2246 vs->csock = -1;
2247 buffer_reset(&vs->input);
2248 buffer_reset(&vs->output);
2249 vs->need_update = 0;
2250 #ifdef CONFIG_VNC_TLS
2251 if (vs->tls_session) {
2252 gnutls_deinit(vs->tls_session);
2253 vs->tls_session = NULL;
2255 vs->wiremode = VNC_WIREMODE_CLEAR;
2256 #endif /* CONFIG_VNC_TLS */
2258 vs->auth = VNC_AUTH_INVALID;
2259 #ifdef CONFIG_VNC_TLS
2260 vs->subauth = VNC_AUTH_INVALID;
2261 vs->x509verify = 0;
2262 #endif
2263 audio_del(vs);
2266 int vnc_display_password(DisplayState *ds, const char *password)
2268 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2270 if (vs->password) {
2271 qemu_free(vs->password);
2272 vs->password = NULL;
2274 if (password && password[0]) {
2275 if (!(vs->password = qemu_strdup(password)))
2276 return -1;
2279 return 0;
2282 int vnc_display_open(DisplayState *ds, const char *display)
2284 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2285 const char *options;
2286 int password = 0;
2287 int reverse = 0;
2288 int to_port = 0;
2289 #ifdef CONFIG_VNC_TLS
2290 int tls = 0, x509 = 0;
2291 #endif
2293 vnc_display_close(ds);
2294 if (strcmp(display, "none") == 0)
2295 return 0;
2297 if (!(vs->display = strdup(display)))
2298 return -1;
2300 options = display;
2301 while ((options = strchr(options, ','))) {
2302 options++;
2303 if (strncmp(options, "password", 8) == 0) {
2304 password = 1; /* Require password auth */
2305 } else if (strncmp(options, "reverse", 7) == 0) {
2306 reverse = 1;
2307 } else if (strncmp(options, "to=", 3) == 0) {
2308 to_port = atoi(options+3) + 5900;
2309 #ifdef CONFIG_VNC_TLS
2310 } else if (strncmp(options, "tls", 3) == 0) {
2311 tls = 1; /* Require TLS */
2312 } else if (strncmp(options, "x509", 4) == 0) {
2313 char *start, *end;
2314 x509 = 1; /* Require x509 certificates */
2315 if (strncmp(options, "x509verify", 10) == 0)
2316 vs->x509verify = 1; /* ...and verify client certs */
2318 /* Now check for 'x509=/some/path' postfix
2319 * and use that to setup x509 certificate/key paths */
2320 start = strchr(options, '=');
2321 end = strchr(options, ',');
2322 if (start && (!end || (start < end))) {
2323 int len = end ? end-(start+1) : strlen(start+1);
2324 char *path = qemu_strndup(start + 1, len);
2326 VNC_DEBUG("Trying certificate path '%s'\n", path);
2327 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2328 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2329 qemu_free(path);
2330 qemu_free(vs->display);
2331 vs->display = NULL;
2332 return -1;
2334 qemu_free(path);
2335 } else {
2336 fprintf(stderr, "No certificate path provided\n");
2337 qemu_free(vs->display);
2338 vs->display = NULL;
2339 return -1;
2341 #endif
2345 if (password) {
2346 #ifdef CONFIG_VNC_TLS
2347 if (tls) {
2348 vs->auth = VNC_AUTH_VENCRYPT;
2349 if (x509) {
2350 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2351 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2352 } else {
2353 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2354 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2356 } else {
2357 #endif
2358 VNC_DEBUG("Initializing VNC server with password auth\n");
2359 vs->auth = VNC_AUTH_VNC;
2360 #ifdef CONFIG_VNC_TLS
2361 vs->subauth = VNC_AUTH_INVALID;
2363 #endif
2364 } else {
2365 #ifdef CONFIG_VNC_TLS
2366 if (tls) {
2367 vs->auth = VNC_AUTH_VENCRYPT;
2368 if (x509) {
2369 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2370 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2371 } else {
2372 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2373 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2375 } else {
2376 #endif
2377 VNC_DEBUG("Initializing VNC server with no auth\n");
2378 vs->auth = VNC_AUTH_NONE;
2379 #ifdef CONFIG_VNC_TLS
2380 vs->subauth = VNC_AUTH_INVALID;
2382 #endif
2385 if (reverse) {
2386 /* connect to viewer */
2387 if (strncmp(display, "unix:", 5) == 0)
2388 vs->lsock = unix_connect(display+5);
2389 else
2390 vs->lsock = inet_connect(display, SOCK_STREAM);
2391 if (-1 == vs->lsock) {
2392 free(vs->display);
2393 vs->display = NULL;
2394 return -1;
2395 } else {
2396 vs->csock = vs->lsock;
2397 vs->lsock = -1;
2398 vnc_connect(vs);
2400 return 0;
2402 } else {
2403 /* listen for connects */
2404 char *dpy;
2405 dpy = qemu_malloc(256);
2406 if (strncmp(display, "unix:", 5) == 0) {
2407 pstrcpy(dpy, 256, "unix:");
2408 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
2409 } else {
2410 vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
2412 if (-1 == vs->lsock) {
2413 free(dpy);
2414 return -1;
2415 } else {
2416 free(vs->display);
2417 vs->display = dpy;
2421 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);