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
26 #include "qemu-common.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"
40 #include <gnutls/gnutls.h>
41 #include <gnutls/x509.h>
42 #endif /* CONFIG_VNC_TLS */
44 // #define _VNC_DEBUG 1
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 */
56 #define VNC_DEBUG(fmt, ...) do { } while (0)
59 #define count_bits(c, v) { \
60 for (c = 0; v; v >>= 1) \
73 typedef struct VncState VncState
;
75 typedef int VncReadEvent(VncState
*vs
, uint8_t *data
, size_t len
);
77 typedef void VncWritePixels(VncState
*vs
, void *data
, int size
);
79 typedef void VncSendHextileTile(VncState
*vs
,
80 int x
, int y
, int w
, int h
,
83 int *has_bg
, int *has_fg
);
85 #define VNC_MAX_WIDTH 2048
86 #define VNC_MAX_HEIGHT 2048
87 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
89 #define VNC_AUTH_CHALLENGE_SIZE 16
100 VNC_AUTH_VENCRYPT
= 19
103 #ifdef CONFIG_VNC_TLS
110 VNC_AUTH_VENCRYPT_PLAIN
= 256,
111 VNC_AUTH_VENCRYPT_TLSNONE
= 257,
112 VNC_AUTH_VENCRYPT_TLSVNC
= 258,
113 VNC_AUTH_VENCRYPT_TLSPLAIN
= 259,
114 VNC_AUTH_VENCRYPT_X509NONE
= 260,
115 VNC_AUTH_VENCRYPT_X509VNC
= 261,
116 VNC_AUTH_VENCRYPT_X509PLAIN
= 262,
119 #define X509_CA_CERT_FILE "ca-cert.pem"
120 #define X509_CA_CRL_FILE "ca-crl.pem"
121 #define X509_SERVER_KEY_FILE "server-key.pem"
122 #define X509_SERVER_CERT_FILE "server-cert.pem"
124 #endif /* CONFIG_VNC_TLS */
133 uint32_t dirty_row
[VNC_MAX_HEIGHT
][VNC_DIRTY_WORDS
];
137 int has_pointer_type_change
;
149 #ifdef CONFIG_VNC_TLS
158 char challenge
[VNC_AUTH_CHALLENGE_SIZE
];
160 #ifdef CONFIG_VNC_TLS
162 gnutls_session_t tls_session
;
167 kbd_layout_t
*kbd_layout
;
168 /* current output mode information */
169 VncWritePixels
*write_pixels
;
170 VncSendHextileTile
*send_hextile_tile
;
171 DisplaySurface clientds
, serverds
;
173 CaptureVoiceOut
*audio_cap
;
174 struct audsettings as
;
176 VncReadEvent
*read_handler
;
177 size_t read_handler_expect
;
179 uint8_t modifiers_state
[256];
182 static VncState
*vnc_state
; /* needed for info vnc */
183 static DisplayChangeListener
*dcl
;
185 void do_info_vnc(void)
187 if (vnc_state
== NULL
|| vnc_state
->display
== NULL
)
188 term_printf("VNC server disabled\n");
190 term_printf("VNC server active on: ");
191 term_print_filename(vnc_state
->display
);
194 if (vnc_state
->csock
== -1)
195 term_printf("No client connected\n");
197 term_printf("Client connected\n");
202 1) Get the queue working for IO.
203 2) there is some weirdness when using the -S option (the screen is grey
204 and not totally invalidated
205 3) resolutions > 1024
208 static void vnc_write(VncState
*vs
, const void *data
, size_t len
);
209 static void vnc_write_u32(VncState
*vs
, uint32_t value
);
210 static void vnc_write_s32(VncState
*vs
, int32_t value
);
211 static void vnc_write_u16(VncState
*vs
, uint16_t value
);
212 static void vnc_write_u8(VncState
*vs
, uint8_t value
);
213 static void vnc_flush(VncState
*vs
);
214 static void vnc_update_client(void *opaque
);
215 static void vnc_client_read(void *opaque
);
217 static void vnc_colordepth(DisplayState
*ds
);
219 static inline void vnc_set_bit(uint32_t *d
, int k
)
221 d
[k
>> 5] |= 1 << (k
& 0x1f);
224 static inline void vnc_clear_bit(uint32_t *d
, int k
)
226 d
[k
>> 5] &= ~(1 << (k
& 0x1f));
229 static inline void vnc_set_bits(uint32_t *d
, int n
, int nb_words
)
239 d
[j
++] = (1 << n
) - 1;
244 static inline int vnc_get_bit(const uint32_t *d
, int k
)
246 return (d
[k
>> 5] >> (k
& 0x1f)) & 1;
249 static inline int vnc_and_bits(const uint32_t *d1
, const uint32_t *d2
,
253 for(i
= 0; i
< nb_words
; i
++) {
254 if ((d1
[i
] & d2
[i
]) != 0)
260 static void vnc_dpy_update(DisplayState
*ds
, int x
, int y
, int w
, int h
)
262 VncState
*vs
= ds
->opaque
;
267 /* round x down to ensure the loop only spans one 16-pixel block per,
268 iteration. otherwise, if (x % 16) != 0, the last iteration may span
269 two 16-pixel blocks but we only mark the first as dirty
274 x
= MIN(x
, vs
->serverds
.width
);
275 y
= MIN(y
, vs
->serverds
.height
);
276 w
= MIN(x
+ w
, vs
->serverds
.width
) - x
;
277 h
= MIN(h
, vs
->serverds
.height
);
280 for (i
= 0; i
< w
; i
+= 16)
281 vnc_set_bit(vs
->dirty_row
[y
], (x
+ i
) / 16);
284 static void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
287 vnc_write_u16(vs
, x
);
288 vnc_write_u16(vs
, y
);
289 vnc_write_u16(vs
, w
);
290 vnc_write_u16(vs
, h
);
292 vnc_write_s32(vs
, encoding
);
295 static void vnc_dpy_resize(DisplayState
*ds
)
298 VncState
*vs
= ds
->opaque
;
300 vs
->old_data
= qemu_realloc(vs
->old_data
, ds_get_linesize(ds
) * ds_get_height(ds
));
302 if (vs
->old_data
== NULL
) {
303 fprintf(stderr
, "vnc: memory allocation failed\n");
307 if (ds_get_bytes_per_pixel(ds
) != vs
->serverds
.pf
.bytes_per_pixel
)
308 console_color_init(ds
);
310 size_changed
= ds_get_width(ds
) != vs
->serverds
.width
||
311 ds_get_height(ds
) != vs
->serverds
.height
;
312 vs
->serverds
= *(ds
->surface
);
314 if (vs
->csock
!= -1 && vs
->has_resize
) {
315 vnc_write_u8(vs
, 0); /* msg id */
317 vnc_write_u16(vs
, 1); /* number of rects */
318 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(ds
), ds_get_height(ds
), -223);
323 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
324 memset(vs
->old_data
, 42, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
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
)
338 r
= ((((v
& vs
->serverds
.pf
.rmask
) >> vs
->serverds
.pf
.rshift
) << vs
->clientds
.pf
.rbits
) >>
339 vs
->serverds
.pf
.rbits
);
340 g
= ((((v
& vs
->serverds
.pf
.gmask
) >> vs
->serverds
.pf
.gshift
) << vs
->clientds
.pf
.gbits
) >>
341 vs
->serverds
.pf
.gbits
);
342 b
= ((((v
& vs
->serverds
.pf
.bmask
) >> vs
->serverds
.pf
.bshift
) << vs
->clientds
.pf
.bbits
) >>
343 vs
->serverds
.pf
.bbits
);
344 v
= (r
<< vs
->clientds
.pf
.rshift
) |
345 (g
<< vs
->clientds
.pf
.gshift
) |
346 (b
<< vs
->clientds
.pf
.bshift
);
347 switch(vs
->clientds
.pf
.bytes_per_pixel
) {
352 if (vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) {
362 if (vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) {
377 static void vnc_write_pixels_generic(VncState
*vs
, void *pixels1
, int size
)
381 if (vs
->serverds
.pf
.bytes_per_pixel
== 4) {
382 uint32_t *pixels
= pixels1
;
385 for(i
= 0; i
< n
; i
++) {
386 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
387 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
389 } else if (vs
->serverds
.pf
.bytes_per_pixel
== 2) {
390 uint16_t *pixels
= pixels1
;
393 for(i
= 0; i
< n
; i
++) {
394 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
395 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
397 } else if (vs
->serverds
.pf
.bytes_per_pixel
== 1) {
398 uint8_t *pixels
= pixels1
;
401 for(i
= 0; i
< n
; i
++) {
402 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
403 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
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
)
415 vnc_framebuffer_update(vs
, x
, y
, w
, h
, 0);
417 row
= ds_get_data(vs
->ds
) + y
* ds_get_linesize(vs
->ds
) + x
* ds_get_bytes_per_pixel(vs
->ds
);
418 for (i
= 0; i
< h
; i
++) {
419 vs
->write_pixels(vs
, row
, w
* ds_get_bytes_per_pixel(vs
->ds
));
420 row
+= ds_get_linesize(vs
->ds
);
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);
431 #include "vnchextile.h"
435 #include "vnchextile.h"
439 #include "vnchextile.h"
444 #include "vnchextile.h"
450 #include "vnchextile.h"
456 #include "vnchextile.h"
460 static void send_framebuffer_update_hextile(VncState
*vs
, int x
, int y
, int w
, int h
)
464 uint8_t *last_fg
, *last_bg
;
466 vnc_framebuffer_update(vs
, x
, y
, w
, h
, 5);
468 last_fg
= (uint8_t *) malloc(vs
->serverds
.pf
.bytes_per_pixel
);
469 last_bg
= (uint8_t *) malloc(vs
->serverds
.pf
.bytes_per_pixel
);
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
);
483 static void send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
486 send_framebuffer_update_hextile(vs
, x
, y
, w
, h
);
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 VncState
*vs
= ds
->opaque
;
495 vnc_update_client(vs
);
497 vnc_write_u8(vs
, 0); /* msg id */
499 vnc_write_u16(vs
, 1); /* number of rects */
500 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, 1);
501 vnc_write_u16(vs
, src_x
);
502 vnc_write_u16(vs
, src_y
);
506 static int find_dirty_height(VncState
*vs
, int y
, int last_x
, int x
)
510 for (h
= 1; h
< (vs
->serverds
.height
- y
); h
++) {
512 if (!vnc_get_bit(vs
->dirty_row
[y
+ h
], last_x
))
514 for (tmp_x
= last_x
; tmp_x
< x
; tmp_x
++)
515 vnc_clear_bit(vs
->dirty_row
[y
+ h
], tmp_x
);
521 static void vnc_update_client(void *opaque
)
523 VncState
*vs
= opaque
;
525 if (vs
->need_update
&& vs
->csock
!= -1) {
529 uint32_t width_mask
[VNC_DIRTY_WORDS
];
536 vnc_set_bits(width_mask
, (ds_get_width(vs
->ds
) / 16), VNC_DIRTY_WORDS
);
538 /* Walk through the dirty map and eliminate tiles that
539 really aren't dirty */
540 row
= ds_get_data(vs
->ds
);
541 old_row
= vs
->old_data
;
543 for (y
= 0; y
< ds_get_height(vs
->ds
); y
++) {
544 if (vnc_and_bits(vs
->dirty_row
[y
], width_mask
, VNC_DIRTY_WORDS
)) {
550 old_ptr
= (char*)old_row
;
552 for (x
= 0; x
< ds_get_width(vs
->ds
); x
+= 16) {
553 if (memcmp(old_ptr
, ptr
, 16 * ds_get_bytes_per_pixel(vs
->ds
)) == 0) {
554 vnc_clear_bit(vs
->dirty_row
[y
], (x
/ 16));
557 memcpy(old_ptr
, ptr
, 16 * ds_get_bytes_per_pixel(vs
->ds
));
560 ptr
+= 16 * ds_get_bytes_per_pixel(vs
->ds
);
561 old_ptr
+= 16 * ds_get_bytes_per_pixel(vs
->ds
);
565 row
+= ds_get_linesize(vs
->ds
);
566 old_row
+= ds_get_linesize(vs
->ds
);
569 if (!has_dirty
&& !vs
->audio_cap
) {
570 qemu_mod_timer(vs
->timer
, qemu_get_clock(rt_clock
) + VNC_REFRESH_INTERVAL
);
574 /* Count rectangles */
576 vnc_write_u8(vs
, 0); /* msg id */
578 saved_offset
= vs
->output
.offset
;
579 vnc_write_u16(vs
, 0);
581 for (y
= 0; y
< vs
->serverds
.height
; y
++) {
584 for (x
= 0; x
< vs
->serverds
.width
/ 16; x
++) {
585 if (vnc_get_bit(vs
->dirty_row
[y
], x
)) {
589 vnc_clear_bit(vs
->dirty_row
[y
], x
);
592 int h
= find_dirty_height(vs
, y
, last_x
, x
);
593 send_framebuffer_update(vs
, last_x
* 16, y
, (x
- last_x
) * 16, h
);
600 int h
= find_dirty_height(vs
, y
, last_x
, x
);
601 send_framebuffer_update(vs
, last_x
* 16, y
, (x
- last_x
) * 16, h
);
605 vs
->output
.buffer
[saved_offset
] = (n_rectangles
>> 8) & 0xFF;
606 vs
->output
.buffer
[saved_offset
+ 1] = n_rectangles
& 0xFF;
611 if (vs
->csock
!= -1) {
612 qemu_mod_timer(vs
->timer
, qemu_get_clock(rt_clock
) + VNC_REFRESH_INTERVAL
);
617 static int vnc_listen_poll(void *opaque
)
619 VncState
*vs
= opaque
;
625 static void buffer_reserve(Buffer
*buffer
, size_t len
)
627 if ((buffer
->capacity
- buffer
->offset
) < len
) {
628 buffer
->capacity
+= (len
+ 1024);
629 buffer
->buffer
= qemu_realloc(buffer
->buffer
, buffer
->capacity
);
630 if (buffer
->buffer
== NULL
) {
631 fprintf(stderr
, "vnc: out of memory\n");
637 static int buffer_empty(Buffer
*buffer
)
639 return buffer
->offset
== 0;
642 static uint8_t *buffer_end(Buffer
*buffer
)
644 return buffer
->buffer
+ buffer
->offset
;
647 static void buffer_reset(Buffer
*buffer
)
652 static void buffer_append(Buffer
*buffer
, const void *data
, size_t len
)
654 memcpy(buffer
->buffer
+ buffer
->offset
, data
, len
);
655 buffer
->offset
+= len
;
659 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
661 VncState
*vs
= opaque
;
664 case AUD_CNOTIFY_DISABLE
:
665 vnc_write_u8(vs
, 255);
667 vnc_write_u16(vs
, 0);
671 case AUD_CNOTIFY_ENABLE
:
672 vnc_write_u8(vs
, 255);
674 vnc_write_u16(vs
, 1);
680 static void audio_capture_destroy(void *opaque
)
684 static void audio_capture(void *opaque
, void *buf
, int size
)
686 VncState
*vs
= opaque
;
688 vnc_write_u8(vs
, 255);
690 vnc_write_u16(vs
, 2);
691 vnc_write_u32(vs
, size
);
692 vnc_write(vs
, buf
, size
);
696 static void audio_add(VncState
*vs
)
698 struct audio_capture_ops ops
;
701 term_printf ("audio already running\n");
705 ops
.notify
= audio_capture_notify
;
706 ops
.destroy
= audio_capture_destroy
;
707 ops
.capture
= audio_capture
;
709 vs
->audio_cap
= AUD_add_capture(NULL
, &vs
->as
, &ops
, vs
);
710 if (!vs
->audio_cap
) {
711 term_printf ("Failed to add audio capture\n");
715 static void audio_del(VncState
*vs
)
718 AUD_del_capture(vs
->audio_cap
, vs
);
719 vs
->audio_cap
= NULL
;
723 static int vnc_client_io_error(VncState
*vs
, int ret
, int last_errno
)
725 if (ret
== 0 || ret
== -1) {
727 switch (last_errno
) {
739 VNC_DEBUG("Closing down client sock %d %d\n", ret
, ret
< 0 ? last_errno
: 0);
740 qemu_set_fd_handler2(vs
->csock
, NULL
, NULL
, NULL
, NULL
);
741 closesocket(vs
->csock
);
744 buffer_reset(&vs
->input
);
745 buffer_reset(&vs
->output
);
747 #ifdef CONFIG_VNC_TLS
748 if (vs
->tls_session
) {
749 gnutls_deinit(vs
->tls_session
);
750 vs
->tls_session
= NULL
;
752 vs
->wiremode
= VNC_WIREMODE_CLEAR
;
753 #endif /* CONFIG_VNC_TLS */
760 static void vnc_client_error(VncState
*vs
)
762 vnc_client_io_error(vs
, -1, EINVAL
);
765 static void vnc_client_write(void *opaque
)
768 VncState
*vs
= opaque
;
770 #ifdef CONFIG_VNC_TLS
771 if (vs
->tls_session
) {
772 ret
= gnutls_write(vs
->tls_session
, vs
->output
.buffer
, vs
->output
.offset
);
774 if (ret
== GNUTLS_E_AGAIN
)
781 #endif /* CONFIG_VNC_TLS */
782 ret
= send(vs
->csock
, vs
->output
.buffer
, vs
->output
.offset
, 0);
783 ret
= vnc_client_io_error(vs
, ret
, socket_error());
787 memmove(vs
->output
.buffer
, vs
->output
.buffer
+ ret
, (vs
->output
.offset
- ret
));
788 vs
->output
.offset
-= ret
;
790 if (vs
->output
.offset
== 0) {
791 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
795 static void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
797 vs
->read_handler
= func
;
798 vs
->read_handler_expect
= expecting
;
801 static void vnc_client_read(void *opaque
)
803 VncState
*vs
= opaque
;
806 buffer_reserve(&vs
->input
, 4096);
808 #ifdef CONFIG_VNC_TLS
809 if (vs
->tls_session
) {
810 ret
= gnutls_read(vs
->tls_session
, buffer_end(&vs
->input
), 4096);
812 if (ret
== GNUTLS_E_AGAIN
)
819 #endif /* CONFIG_VNC_TLS */
820 ret
= recv(vs
->csock
, buffer_end(&vs
->input
), 4096, 0);
821 ret
= vnc_client_io_error(vs
, ret
, socket_error());
825 vs
->input
.offset
+= ret
;
827 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
828 size_t len
= vs
->read_handler_expect
;
831 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
836 memmove(vs
->input
.buffer
, vs
->input
.buffer
+ len
, (vs
->input
.offset
- len
));
837 vs
->input
.offset
-= len
;
839 vs
->read_handler_expect
= ret
;
844 static void vnc_write(VncState
*vs
, const void *data
, size_t len
)
846 buffer_reserve(&vs
->output
, len
);
848 if (buffer_empty(&vs
->output
)) {
849 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
852 buffer_append(&vs
->output
, data
, len
);
855 static void vnc_write_s32(VncState
*vs
, int32_t value
)
857 vnc_write_u32(vs
, *(uint32_t *)&value
);
860 static void vnc_write_u32(VncState
*vs
, uint32_t value
)
864 buf
[0] = (value
>> 24) & 0xFF;
865 buf
[1] = (value
>> 16) & 0xFF;
866 buf
[2] = (value
>> 8) & 0xFF;
867 buf
[3] = value
& 0xFF;
869 vnc_write(vs
, buf
, 4);
872 static void vnc_write_u16(VncState
*vs
, uint16_t value
)
876 buf
[0] = (value
>> 8) & 0xFF;
877 buf
[1] = value
& 0xFF;
879 vnc_write(vs
, buf
, 2);
882 static void vnc_write_u8(VncState
*vs
, uint8_t value
)
884 vnc_write(vs
, (char *)&value
, 1);
887 static void vnc_flush(VncState
*vs
)
889 if (vs
->output
.offset
)
890 vnc_client_write(vs
);
893 static uint8_t read_u8(uint8_t *data
, size_t offset
)
898 static uint16_t read_u16(uint8_t *data
, size_t offset
)
900 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
903 static int32_t read_s32(uint8_t *data
, size_t offset
)
905 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
906 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
909 static uint32_t read_u32(uint8_t *data
, size_t offset
)
911 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
912 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
915 #ifdef CONFIG_VNC_TLS
916 static ssize_t
vnc_tls_push(gnutls_transport_ptr_t transport
,
919 struct VncState
*vs
= (struct VncState
*)transport
;
923 ret
= send(vs
->csock
, data
, len
, 0);
933 static ssize_t
vnc_tls_pull(gnutls_transport_ptr_t transport
,
936 struct VncState
*vs
= (struct VncState
*)transport
;
940 ret
= recv(vs
->csock
, data
, len
, 0);
948 #endif /* CONFIG_VNC_TLS */
950 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
954 static void check_pointer_type_change(VncState
*vs
, int absolute
)
956 if (vs
->has_pointer_type_change
&& vs
->absolute
!= absolute
) {
959 vnc_write_u16(vs
, 1);
960 vnc_framebuffer_update(vs
, absolute
, 0,
961 ds_get_width(vs
->ds
), ds_get_height(vs
->ds
), -257);
964 vs
->absolute
= absolute
;
967 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
972 if (button_mask
& 0x01)
973 buttons
|= MOUSE_EVENT_LBUTTON
;
974 if (button_mask
& 0x02)
975 buttons
|= MOUSE_EVENT_MBUTTON
;
976 if (button_mask
& 0x04)
977 buttons
|= MOUSE_EVENT_RBUTTON
;
978 if (button_mask
& 0x08)
980 if (button_mask
& 0x10)
984 kbd_mouse_event(x
* 0x7FFF / (ds_get_width(vs
->ds
) - 1),
985 y
* 0x7FFF / (ds_get_height(vs
->ds
) - 1),
987 } else if (vs
->has_pointer_type_change
) {
991 kbd_mouse_event(x
, y
, dz
, buttons
);
993 if (vs
->last_x
!= -1)
994 kbd_mouse_event(x
- vs
->last_x
,
1001 check_pointer_type_change(vs
, kbd_mouse_is_absolute());
1004 static void reset_keys(VncState
*vs
)
1007 for(i
= 0; i
< 256; i
++) {
1008 if (vs
->modifiers_state
[i
]) {
1010 kbd_put_keycode(0xe0);
1011 kbd_put_keycode(i
| 0x80);
1012 vs
->modifiers_state
[i
] = 0;
1017 static void press_key(VncState
*vs
, int keysym
)
1019 kbd_put_keycode(keysym2scancode(vs
->kbd_layout
, keysym
) & 0x7f);
1020 kbd_put_keycode(keysym2scancode(vs
->kbd_layout
, keysym
) | 0x80);
1023 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1025 /* QEMU console switch */
1027 case 0x2a: /* Left Shift */
1028 case 0x36: /* Right Shift */
1029 case 0x1d: /* Left CTRL */
1030 case 0x9d: /* Right CTRL */
1031 case 0x38: /* Left ALT */
1032 case 0xb8: /* Right ALT */
1034 vs
->modifiers_state
[keycode
] = 1;
1036 vs
->modifiers_state
[keycode
] = 0;
1038 case 0x02 ... 0x0a: /* '1' to '9' keys */
1039 if (down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1040 /* Reset the modifiers sent to the current console */
1042 console_select(keycode
- 0x02);
1046 case 0x3a: /* CapsLock */
1047 case 0x45: /* NumLock */
1049 vs
->modifiers_state
[keycode
] ^= 1;
1053 if (keycode_is_keypad(vs
->kbd_layout
, keycode
)) {
1054 /* If the numlock state needs to change then simulate an additional
1055 keypress before sending this one. This will happen if the user
1056 toggles numlock away from the VNC window.
1058 if (keysym_is_numlock(vs
->kbd_layout
, sym
& 0xFFFF)) {
1059 if (!vs
->modifiers_state
[0x45]) {
1060 vs
->modifiers_state
[0x45] = 1;
1061 press_key(vs
, 0xff7f);
1064 if (vs
->modifiers_state
[0x45]) {
1065 vs
->modifiers_state
[0x45] = 0;
1066 press_key(vs
, 0xff7f);
1071 if (is_graphic_console()) {
1073 kbd_put_keycode(0xe0);
1075 kbd_put_keycode(keycode
& 0x7f);
1077 kbd_put_keycode(keycode
| 0x80);
1079 /* QEMU console emulation */
1082 case 0x2a: /* Left Shift */
1083 case 0x36: /* Right Shift */
1084 case 0x1d: /* Left CTRL */
1085 case 0x9d: /* Right CTRL */
1086 case 0x38: /* Left ALT */
1087 case 0xb8: /* Right ALT */
1090 kbd_put_keysym(QEMU_KEY_UP
);
1093 kbd_put_keysym(QEMU_KEY_DOWN
);
1096 kbd_put_keysym(QEMU_KEY_LEFT
);
1099 kbd_put_keysym(QEMU_KEY_RIGHT
);
1102 kbd_put_keysym(QEMU_KEY_DELETE
);
1105 kbd_put_keysym(QEMU_KEY_HOME
);
1108 kbd_put_keysym(QEMU_KEY_END
);
1111 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1114 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1117 kbd_put_keysym(sym
);
1124 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1128 if (sym
>= 'A' && sym
<= 'Z' && is_graphic_console())
1129 sym
= sym
- 'A' + 'a';
1131 keycode
= keysym2scancode(vs
->kbd_layout
, sym
& 0xFFFF);
1132 do_key_event(vs
, down
, keycode
, sym
);
1135 static void ext_key_event(VncState
*vs
, int down
,
1136 uint32_t sym
, uint16_t keycode
)
1138 /* if the user specifies a keyboard layout, always use it */
1139 if (keyboard_layout
)
1140 key_event(vs
, down
, sym
);
1142 do_key_event(vs
, down
, keycode
, sym
);
1145 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1146 int x_position
, int y_position
,
1149 if (x_position
> ds_get_width(vs
->ds
))
1150 x_position
= ds_get_width(vs
->ds
);
1151 if (y_position
> ds_get_height(vs
->ds
))
1152 y_position
= ds_get_height(vs
->ds
);
1153 if (x_position
+ w
>= ds_get_width(vs
->ds
))
1154 w
= ds_get_width(vs
->ds
) - x_position
;
1155 if (y_position
+ h
>= ds_get_height(vs
->ds
))
1156 h
= ds_get_height(vs
->ds
) - y_position
;
1159 vs
->need_update
= 1;
1161 char *old_row
= vs
->old_data
+ y_position
* ds_get_linesize(vs
->ds
);
1163 for (i
= 0; i
< h
; i
++) {
1164 vnc_set_bits(vs
->dirty_row
[y_position
+ i
],
1165 (ds_get_width(vs
->ds
) / 16), VNC_DIRTY_WORDS
);
1166 memset(old_row
, 42, ds_get_width(vs
->ds
) * ds_get_bytes_per_pixel(vs
->ds
));
1167 old_row
+= ds_get_linesize(vs
->ds
);
1172 static void send_ext_key_event_ack(VncState
*vs
)
1174 vnc_write_u8(vs
, 0);
1175 vnc_write_u8(vs
, 0);
1176 vnc_write_u16(vs
, 1);
1177 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
), ds_get_height(vs
->ds
), -258);
1181 static void send_ext_audio_ack(VncState
*vs
)
1183 vnc_write_u8(vs
, 0);
1184 vnc_write_u8(vs
, 0);
1185 vnc_write_u16(vs
, 1);
1186 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
), ds_get_height(vs
->ds
), -259);
1190 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1194 vs
->has_hextile
= 0;
1196 vs
->has_pointer_type_change
= 0;
1199 dcl
->dpy_copy
= NULL
;
1201 for (i
= n_encodings
- 1; i
>= 0; i
--) {
1202 switch (encodings
[i
]) {
1204 vs
->has_hextile
= 0;
1206 case 1: /* CopyRect */
1207 dcl
->dpy_copy
= vnc_copy
;
1209 case 5: /* Hextile */
1210 vs
->has_hextile
= 1;
1212 case -223: /* DesktopResize */
1216 vs
->has_pointer_type_change
= 1;
1219 send_ext_key_event_ack(vs
);
1222 send_ext_audio_ack(vs
);
1232 check_pointer_type_change(vs
, kbd_mouse_is_absolute());
1235 static void set_pixel_conversion(VncState
*vs
)
1237 if ((vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) ==
1238 (vs
->ds
->surface
->flags
& QEMU_BIG_ENDIAN_FLAG
) &&
1239 !memcmp(&(vs
->clientds
.pf
), &(vs
->ds
->surface
->pf
), sizeof(PixelFormat
))) {
1240 vs
->write_pixels
= vnc_write_pixels_copy
;
1241 switch (vs
->ds
->surface
->pf
.bits_per_pixel
) {
1243 vs
->send_hextile_tile
= send_hextile_tile_8
;
1246 vs
->send_hextile_tile
= send_hextile_tile_16
;
1249 vs
->send_hextile_tile
= send_hextile_tile_32
;
1253 vs
->write_pixels
= vnc_write_pixels_generic
;
1254 switch (vs
->ds
->surface
->pf
.bits_per_pixel
) {
1256 vs
->send_hextile_tile
= send_hextile_tile_generic_8
;
1259 vs
->send_hextile_tile
= send_hextile_tile_generic_16
;
1262 vs
->send_hextile_tile
= send_hextile_tile_generic_32
;
1268 static void set_pixel_format(VncState
*vs
,
1269 int bits_per_pixel
, int depth
,
1270 int big_endian_flag
, int true_color_flag
,
1271 int red_max
, int green_max
, int blue_max
,
1272 int red_shift
, int green_shift
, int blue_shift
)
1274 if (!true_color_flag
) {
1275 vnc_client_error(vs
);
1279 vs
->clientds
= vs
->serverds
;
1280 vs
->clientds
.pf
.rmax
= red_max
;
1281 count_bits(vs
->clientds
.pf
.rbits
, red_max
);
1282 vs
->clientds
.pf
.rshift
= red_shift
;
1283 vs
->clientds
.pf
.rmask
= red_max
<< red_shift
;
1284 vs
->clientds
.pf
.gmax
= green_max
;
1285 count_bits(vs
->clientds
.pf
.gbits
, green_max
);
1286 vs
->clientds
.pf
.gshift
= green_shift
;
1287 vs
->clientds
.pf
.gmask
= green_max
<< green_shift
;
1288 vs
->clientds
.pf
.bmax
= blue_max
;
1289 count_bits(vs
->clientds
.pf
.bbits
, blue_max
);
1290 vs
->clientds
.pf
.bshift
= blue_shift
;
1291 vs
->clientds
.pf
.bmask
= blue_max
<< blue_shift
;
1292 vs
->clientds
.pf
.bits_per_pixel
= bits_per_pixel
;
1293 vs
->clientds
.pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
1294 vs
->clientds
.pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
1295 vs
->clientds
.flags
= big_endian_flag
? QEMU_BIG_ENDIAN_FLAG
: 0x00;
1297 set_pixel_conversion(vs
);
1299 vga_hw_invalidate();
1303 static void pixel_format_message (VncState
*vs
) {
1304 char pad
[3] = { 0, 0, 0 };
1306 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.bits_per_pixel
); /* bits-per-pixel */
1307 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.depth
); /* depth */
1309 #ifdef WORDS_BIGENDIAN
1310 vnc_write_u8(vs
, 1); /* big-endian-flag */
1312 vnc_write_u8(vs
, 0); /* big-endian-flag */
1314 vnc_write_u8(vs
, 1); /* true-color-flag */
1315 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.rmax
); /* red-max */
1316 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.gmax
); /* green-max */
1317 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.bmax
); /* blue-max */
1318 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.rshift
); /* red-shift */
1319 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.gshift
); /* green-shift */
1320 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.bshift
); /* blue-shift */
1321 if (vs
->ds
->surface
->pf
.bits_per_pixel
== 32)
1322 vs
->send_hextile_tile
= send_hextile_tile_32
;
1323 else if (vs
->ds
->surface
->pf
.bits_per_pixel
== 16)
1324 vs
->send_hextile_tile
= send_hextile_tile_16
;
1325 else if (vs
->ds
->surface
->pf
.bits_per_pixel
== 8)
1326 vs
->send_hextile_tile
= send_hextile_tile_8
;
1327 vs
->clientds
= *(vs
->ds
->surface
);
1328 vs
->clientds
.flags
|= ~QEMU_ALLOCATED_FLAG
;
1329 vs
->write_pixels
= vnc_write_pixels_copy
;
1331 vnc_write(vs
, pad
, 3); /* padding */
1334 static void vnc_dpy_setdata(DisplayState
*ds
)
1336 /* We don't have to do anything */
1339 static void vnc_colordepth(DisplayState
*ds
)
1341 struct VncState
*vs
= ds
->opaque
;
1343 if (vs
->csock
!= -1 && vs
->has_WMVi
) {
1344 /* Sending a WMVi message to notify the client*/
1345 vnc_write_u8(vs
, 0); /* msg id */
1346 vnc_write_u8(vs
, 0);
1347 vnc_write_u16(vs
, 1); /* number of rects */
1348 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(ds
), ds_get_height(ds
), 0x574D5669);
1349 pixel_format_message(vs
);
1352 set_pixel_conversion(vs
);
1356 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
1366 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
1367 read_u8(data
, 6), read_u8(data
, 7),
1368 read_u16(data
, 8), read_u16(data
, 10),
1369 read_u16(data
, 12), read_u8(data
, 14),
1370 read_u8(data
, 15), read_u8(data
, 16));
1377 limit
= read_u16(data
, 2);
1379 return 4 + (limit
* 4);
1381 limit
= read_u16(data
, 2);
1383 for (i
= 0; i
< limit
; i
++) {
1384 int32_t val
= read_s32(data
, 4 + (i
* 4));
1385 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
1388 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
1394 framebuffer_update_request(vs
,
1395 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
1396 read_u16(data
, 6), read_u16(data
, 8));
1402 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
1408 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
1415 uint32_t dlen
= read_u32(data
, 4);
1420 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
1426 switch (read_u8(data
, 1)) {
1431 ext_key_event(vs
, read_u16(data
, 2),
1432 read_u32(data
, 4), read_u32(data
, 8));
1438 switch (read_u16 (data
, 2)) {
1448 switch (read_u8(data
, 4)) {
1449 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
1450 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
1451 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
1452 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
1453 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
1454 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
1456 printf("Invalid audio format %d\n", read_u8(data
, 4));
1457 vnc_client_error(vs
);
1460 vs
->as
.nchannels
= read_u8(data
, 5);
1461 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
1462 printf("Invalid audio channel coount %d\n",
1464 vnc_client_error(vs
);
1467 vs
->as
.freq
= read_u32(data
, 6);
1470 printf ("Invalid audio message %d\n", read_u8(data
, 4));
1471 vnc_client_error(vs
);
1477 printf("Msg: %d\n", read_u16(data
, 0));
1478 vnc_client_error(vs
);
1483 printf("Msg: %d\n", data
[0]);
1484 vnc_client_error(vs
);
1488 vnc_read_when(vs
, protocol_client_msg
, 1);
1492 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
1497 vnc_write_u16(vs
, ds_get_width(vs
->ds
));
1498 vnc_write_u16(vs
, ds_get_height(vs
->ds
));
1500 pixel_format_message(vs
);
1503 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
1505 size
= snprintf(buf
, sizeof(buf
), "QEMU");
1507 vnc_write_u32(vs
, size
);
1508 vnc_write(vs
, buf
, size
);
1511 vnc_read_when(vs
, protocol_client_msg
, 1);
1516 static void make_challenge(VncState
*vs
)
1520 srand(time(NULL
)+getpid()+getpid()*987654+rand());
1522 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
1523 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
1526 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
1528 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
1530 unsigned char key
[8];
1532 if (!vs
->password
|| !vs
->password
[0]) {
1533 VNC_DEBUG("No password configured on server");
1534 vnc_write_u32(vs
, 1); /* Reject auth */
1535 if (vs
->minor
>= 8) {
1536 static const char err
[] = "Authentication failed";
1537 vnc_write_u32(vs
, sizeof(err
));
1538 vnc_write(vs
, err
, sizeof(err
));
1541 vnc_client_error(vs
);
1545 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
1547 /* Calculate the expected challenge response */
1548 pwlen
= strlen(vs
->password
);
1549 for (i
=0; i
<sizeof(key
); i
++)
1550 key
[i
] = i
<pwlen
? vs
->password
[i
] : 0;
1552 for (j
= 0; j
< VNC_AUTH_CHALLENGE_SIZE
; j
+= 8)
1553 des(response
+j
, response
+j
);
1555 /* Compare expected vs actual challenge response */
1556 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
1557 VNC_DEBUG("Client challenge reponse did not match\n");
1558 vnc_write_u32(vs
, 1); /* Reject auth */
1559 if (vs
->minor
>= 8) {
1560 static const char err
[] = "Authentication failed";
1561 vnc_write_u32(vs
, sizeof(err
));
1562 vnc_write(vs
, err
, sizeof(err
));
1565 vnc_client_error(vs
);
1567 VNC_DEBUG("Accepting VNC challenge response\n");
1568 vnc_write_u32(vs
, 0); /* Accept auth */
1571 vnc_read_when(vs
, protocol_client_init
, 1);
1576 static int start_auth_vnc(VncState
*vs
)
1579 /* Send client a 'random' challenge */
1580 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
1583 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
1588 #ifdef CONFIG_VNC_TLS
1589 #define DH_BITS 1024
1590 static gnutls_dh_params_t dh_params
;
1592 static int vnc_tls_initialize(void)
1594 static int tlsinitialized
= 0;
1599 if (gnutls_global_init () < 0)
1602 /* XXX ought to re-generate diffie-hellmen params periodically */
1603 if (gnutls_dh_params_init (&dh_params
) < 0)
1605 if (gnutls_dh_params_generate2 (dh_params
, DH_BITS
) < 0)
1608 #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
1609 gnutls_global_set_log_level(10);
1610 gnutls_global_set_log_function(vnc_debug_gnutls_log
);
1618 static gnutls_anon_server_credentials
vnc_tls_initialize_anon_cred(void)
1620 gnutls_anon_server_credentials anon_cred
;
1623 if ((ret
= gnutls_anon_allocate_server_credentials(&anon_cred
)) < 0) {
1624 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1628 gnutls_anon_set_server_dh_params(anon_cred
, dh_params
);
1634 static gnutls_certificate_credentials_t
vnc_tls_initialize_x509_cred(VncState
*vs
)
1636 gnutls_certificate_credentials_t x509_cred
;
1639 if (!vs
->x509cacert
) {
1640 VNC_DEBUG("No CA x509 certificate specified\n");
1643 if (!vs
->x509cert
) {
1644 VNC_DEBUG("No server x509 certificate specified\n");
1648 VNC_DEBUG("No server private key specified\n");
1652 if ((ret
= gnutls_certificate_allocate_credentials(&x509_cred
)) < 0) {
1653 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1656 if ((ret
= gnutls_certificate_set_x509_trust_file(x509_cred
,
1658 GNUTLS_X509_FMT_PEM
)) < 0) {
1659 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret
));
1660 gnutls_certificate_free_credentials(x509_cred
);
1664 if ((ret
= gnutls_certificate_set_x509_key_file (x509_cred
,
1667 GNUTLS_X509_FMT_PEM
)) < 0) {
1668 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret
));
1669 gnutls_certificate_free_credentials(x509_cred
);
1673 if (vs
->x509cacrl
) {
1674 if ((ret
= gnutls_certificate_set_x509_crl_file(x509_cred
,
1676 GNUTLS_X509_FMT_PEM
)) < 0) {
1677 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret
));
1678 gnutls_certificate_free_credentials(x509_cred
);
1683 gnutls_certificate_set_dh_params (x509_cred
, dh_params
);
1688 static int vnc_validate_certificate(struct VncState
*vs
)
1691 unsigned int status
;
1692 const gnutls_datum_t
*certs
;
1693 unsigned int nCerts
, i
;
1696 VNC_DEBUG("Validating client certificate\n");
1697 if ((ret
= gnutls_certificate_verify_peers2 (vs
->tls_session
, &status
)) < 0) {
1698 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret
));
1702 if ((now
= time(NULL
)) == ((time_t)-1)) {
1707 if (status
& GNUTLS_CERT_INVALID
)
1708 VNC_DEBUG("The certificate is not trusted.\n");
1710 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
1711 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1713 if (status
& GNUTLS_CERT_REVOKED
)
1714 VNC_DEBUG("The certificate has been revoked.\n");
1716 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1717 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1721 VNC_DEBUG("Certificate is valid!\n");
1724 /* Only support x509 for now */
1725 if (gnutls_certificate_type_get(vs
->tls_session
) != GNUTLS_CRT_X509
)
1728 if (!(certs
= gnutls_certificate_get_peers(vs
->tls_session
, &nCerts
)))
1731 for (i
= 0 ; i
< nCerts
; i
++) {
1732 gnutls_x509_crt_t cert
;
1733 VNC_DEBUG ("Checking certificate chain %d\n", i
);
1734 if (gnutls_x509_crt_init (&cert
) < 0)
1737 if (gnutls_x509_crt_import(cert
, &certs
[i
], GNUTLS_X509_FMT_DER
) < 0) {
1738 gnutls_x509_crt_deinit (cert
);
1742 if (gnutls_x509_crt_get_expiration_time (cert
) < now
) {
1743 VNC_DEBUG("The certificate has expired\n");
1744 gnutls_x509_crt_deinit (cert
);
1748 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1749 VNC_DEBUG("The certificate is not yet activated\n");
1750 gnutls_x509_crt_deinit (cert
);
1754 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1755 VNC_DEBUG("The certificate is not yet activated\n");
1756 gnutls_x509_crt_deinit (cert
);
1760 gnutls_x509_crt_deinit (cert
);
1767 static int start_auth_vencrypt_subauth(VncState
*vs
)
1769 switch (vs
->subauth
) {
1770 case VNC_AUTH_VENCRYPT_TLSNONE
:
1771 case VNC_AUTH_VENCRYPT_X509NONE
:
1772 VNC_DEBUG("Accept TLS auth none\n");
1773 vnc_write_u32(vs
, 0); /* Accept auth completion */
1774 vnc_read_when(vs
, protocol_client_init
, 1);
1777 case VNC_AUTH_VENCRYPT_TLSVNC
:
1778 case VNC_AUTH_VENCRYPT_X509VNC
:
1779 VNC_DEBUG("Start TLS auth VNC\n");
1780 return start_auth_vnc(vs
);
1782 default: /* Should not be possible, but just in case */
1783 VNC_DEBUG("Reject auth %d\n", vs
->auth
);
1784 vnc_write_u8(vs
, 1);
1785 if (vs
->minor
>= 8) {
1786 static const char err
[] = "Unsupported authentication type";
1787 vnc_write_u32(vs
, sizeof(err
));
1788 vnc_write(vs
, err
, sizeof(err
));
1790 vnc_client_error(vs
);
1796 static void vnc_handshake_io(void *opaque
);
1798 static int vnc_continue_handshake(struct VncState
*vs
) {
1801 if ((ret
= gnutls_handshake(vs
->tls_session
)) < 0) {
1802 if (!gnutls_error_is_fatal(ret
)) {
1803 VNC_DEBUG("Handshake interrupted (blocking)\n");
1804 if (!gnutls_record_get_direction(vs
->tls_session
))
1805 qemu_set_fd_handler(vs
->csock
, vnc_handshake_io
, NULL
, vs
);
1807 qemu_set_fd_handler(vs
->csock
, NULL
, vnc_handshake_io
, vs
);
1810 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret
));
1811 vnc_client_error(vs
);
1815 if (vs
->x509verify
) {
1816 if (vnc_validate_certificate(vs
) < 0) {
1817 VNC_DEBUG("Client verification failed\n");
1818 vnc_client_error(vs
);
1821 VNC_DEBUG("Client verification passed\n");
1825 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1826 vs
->wiremode
= VNC_WIREMODE_TLS
;
1827 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
1829 return start_auth_vencrypt_subauth(vs
);
1832 static void vnc_handshake_io(void *opaque
) {
1833 struct VncState
*vs
= (struct VncState
*)opaque
;
1835 VNC_DEBUG("Handshake IO continue\n");
1836 vnc_continue_handshake(vs
);
1839 #define NEED_X509_AUTH(vs) \
1840 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1841 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1842 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1845 static int vnc_start_tls(struct VncState
*vs
) {
1846 static const int cert_type_priority
[] = { GNUTLS_CRT_X509
, 0 };
1847 static const int protocol_priority
[]= { GNUTLS_TLS1_1
, GNUTLS_TLS1_0
, GNUTLS_SSL3
, 0 };
1848 static const int kx_anon
[] = {GNUTLS_KX_ANON_DH
, 0};
1849 static const int kx_x509
[] = {GNUTLS_KX_DHE_DSS
, GNUTLS_KX_RSA
, GNUTLS_KX_DHE_RSA
, GNUTLS_KX_SRP
, 0};
1851 VNC_DEBUG("Do TLS setup\n");
1852 if (vnc_tls_initialize() < 0) {
1853 VNC_DEBUG("Failed to init TLS\n");
1854 vnc_client_error(vs
);
1857 if (vs
->tls_session
== NULL
) {
1858 if (gnutls_init(&vs
->tls_session
, GNUTLS_SERVER
) < 0) {
1859 vnc_client_error(vs
);
1863 if (gnutls_set_default_priority(vs
->tls_session
) < 0) {
1864 gnutls_deinit(vs
->tls_session
);
1865 vs
->tls_session
= NULL
;
1866 vnc_client_error(vs
);
1870 if (gnutls_kx_set_priority(vs
->tls_session
, NEED_X509_AUTH(vs
) ? kx_x509
: kx_anon
) < 0) {
1871 gnutls_deinit(vs
->tls_session
);
1872 vs
->tls_session
= NULL
;
1873 vnc_client_error(vs
);
1877 if (gnutls_certificate_type_set_priority(vs
->tls_session
, cert_type_priority
) < 0) {
1878 gnutls_deinit(vs
->tls_session
);
1879 vs
->tls_session
= NULL
;
1880 vnc_client_error(vs
);
1884 if (gnutls_protocol_set_priority(vs
->tls_session
, protocol_priority
) < 0) {
1885 gnutls_deinit(vs
->tls_session
);
1886 vs
->tls_session
= NULL
;
1887 vnc_client_error(vs
);
1891 if (NEED_X509_AUTH(vs
)) {
1892 gnutls_certificate_server_credentials x509_cred
= vnc_tls_initialize_x509_cred(vs
);
1894 gnutls_deinit(vs
->tls_session
);
1895 vs
->tls_session
= NULL
;
1896 vnc_client_error(vs
);
1899 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_CERTIFICATE
, x509_cred
) < 0) {
1900 gnutls_deinit(vs
->tls_session
);
1901 vs
->tls_session
= NULL
;
1902 gnutls_certificate_free_credentials(x509_cred
);
1903 vnc_client_error(vs
);
1906 if (vs
->x509verify
) {
1907 VNC_DEBUG("Requesting a client certificate\n");
1908 gnutls_certificate_server_set_request (vs
->tls_session
, GNUTLS_CERT_REQUEST
);
1912 gnutls_anon_server_credentials anon_cred
= vnc_tls_initialize_anon_cred();
1914 gnutls_deinit(vs
->tls_session
);
1915 vs
->tls_session
= NULL
;
1916 vnc_client_error(vs
);
1919 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_ANON
, anon_cred
) < 0) {
1920 gnutls_deinit(vs
->tls_session
);
1921 vs
->tls_session
= NULL
;
1922 gnutls_anon_free_server_credentials(anon_cred
);
1923 vnc_client_error(vs
);
1928 gnutls_transport_set_ptr(vs
->tls_session
, (gnutls_transport_ptr_t
)vs
);
1929 gnutls_transport_set_push_function(vs
->tls_session
, vnc_tls_push
);
1930 gnutls_transport_set_pull_function(vs
->tls_session
, vnc_tls_pull
);
1933 VNC_DEBUG("Start TLS handshake process\n");
1934 return vnc_continue_handshake(vs
);
1937 static int protocol_client_vencrypt_auth(VncState
*vs
, uint8_t *data
, size_t len
)
1939 int auth
= read_u32(data
, 0);
1941 if (auth
!= vs
->subauth
) {
1942 VNC_DEBUG("Rejecting auth %d\n", auth
);
1943 vnc_write_u8(vs
, 0); /* Reject auth */
1945 vnc_client_error(vs
);
1947 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth
);
1948 vnc_write_u8(vs
, 1); /* Accept auth */
1951 if (vnc_start_tls(vs
) < 0) {
1952 VNC_DEBUG("Failed to complete TLS\n");
1956 if (vs
->wiremode
== VNC_WIREMODE_TLS
) {
1957 VNC_DEBUG("Starting VeNCrypt subauth\n");
1958 return start_auth_vencrypt_subauth(vs
);
1960 VNC_DEBUG("TLS handshake blocked\n");
1967 static int protocol_client_vencrypt_init(VncState
*vs
, uint8_t *data
, size_t len
)
1971 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data
[0], (int)data
[1]);
1972 vnc_write_u8(vs
, 1); /* Reject version */
1974 vnc_client_error(vs
);
1976 VNC_DEBUG("Sending allowed auth %d\n", vs
->subauth
);
1977 vnc_write_u8(vs
, 0); /* Accept version */
1978 vnc_write_u8(vs
, 1); /* Number of sub-auths */
1979 vnc_write_u32(vs
, vs
->subauth
); /* The supported auth */
1981 vnc_read_when(vs
, protocol_client_vencrypt_auth
, 4);
1986 static int start_auth_vencrypt(VncState
*vs
)
1988 /* Send VeNCrypt version 0.2 */
1989 vnc_write_u8(vs
, 0);
1990 vnc_write_u8(vs
, 2);
1992 vnc_read_when(vs
, protocol_client_vencrypt_init
, 2);
1995 #endif /* CONFIG_VNC_TLS */
1997 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
1999 /* We only advertise 1 auth scheme at a time, so client
2000 * must pick the one we sent. Verify this */
2001 if (data
[0] != vs
->auth
) { /* Reject auth */
2002 VNC_DEBUG("Reject auth %d\n", (int)data
[0]);
2003 vnc_write_u32(vs
, 1);
2004 if (vs
->minor
>= 8) {
2005 static const char err
[] = "Authentication failed";
2006 vnc_write_u32(vs
, sizeof(err
));
2007 vnc_write(vs
, err
, sizeof(err
));
2009 vnc_client_error(vs
);
2010 } else { /* Accept requested auth */
2011 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2014 VNC_DEBUG("Accept auth none\n");
2015 if (vs
->minor
>= 8) {
2016 vnc_write_u32(vs
, 0); /* Accept auth completion */
2019 vnc_read_when(vs
, protocol_client_init
, 1);
2023 VNC_DEBUG("Start VNC auth\n");
2024 return start_auth_vnc(vs
);
2026 #ifdef CONFIG_VNC_TLS
2027 case VNC_AUTH_VENCRYPT
:
2028 VNC_DEBUG("Accept VeNCrypt auth\n");;
2029 return start_auth_vencrypt(vs
);
2030 #endif /* CONFIG_VNC_TLS */
2032 default: /* Should not be possible, but just in case */
2033 VNC_DEBUG("Reject auth %d\n", vs
->auth
);
2034 vnc_write_u8(vs
, 1);
2035 if (vs
->minor
>= 8) {
2036 static const char err
[] = "Authentication failed";
2037 vnc_write_u32(vs
, sizeof(err
));
2038 vnc_write(vs
, err
, sizeof(err
));
2040 vnc_client_error(vs
);
2046 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2050 memcpy(local
, version
, 12);
2053 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2054 VNC_DEBUG("Malformed protocol version %s\n", local
);
2055 vnc_client_error(vs
);
2058 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2059 if (vs
->major
!= 3 ||
2065 VNC_DEBUG("Unsupported client version\n");
2066 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2068 vnc_client_error(vs
);
2071 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2072 * as equivalent to v3.3 by servers
2074 if (vs
->minor
== 4 || vs
->minor
== 5)
2077 if (vs
->minor
== 3) {
2078 if (vs
->auth
== VNC_AUTH_NONE
) {
2079 VNC_DEBUG("Tell client auth none\n");
2080 vnc_write_u32(vs
, vs
->auth
);
2082 vnc_read_when(vs
, protocol_client_init
, 1);
2083 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2084 VNC_DEBUG("Tell client VNC auth\n");
2085 vnc_write_u32(vs
, vs
->auth
);
2089 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2090 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2092 vnc_client_error(vs
);
2095 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2096 vnc_write_u8(vs
, 1); /* num auth */
2097 vnc_write_u8(vs
, vs
->auth
);
2098 vnc_read_when(vs
, protocol_client_auth
, 1);
2105 static void vnc_connect(VncState
*vs
)
2107 VNC_DEBUG("New client on socket %d\n", vs
->csock
);
2109 socket_set_nonblock(vs
->csock
);
2110 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
2111 vnc_write(vs
, "RFB 003.008\n", 12);
2113 vnc_read_when(vs
, protocol_version
, 12);
2114 memset(vs
->old_data
, 0, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
2115 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
2117 vs
->has_hextile
= 0;
2119 dcl
->dpy_copy
= NULL
;
2120 vnc_update_client(vs
);
2124 static void vnc_listen_read(void *opaque
)
2126 VncState
*vs
= opaque
;
2127 struct sockaddr_in addr
;
2128 socklen_t addrlen
= sizeof(addr
);
2133 vs
->csock
= accept(vs
->lsock
, (struct sockaddr
*)&addr
, &addrlen
);
2134 if (vs
->csock
!= -1) {
2139 void vnc_display_init(DisplayState
*ds
)
2143 vs
= qemu_mallocz(sizeof(VncState
));
2144 dcl
= qemu_mallocz(sizeof(DisplayChangeListener
));
2152 vs
->password
= NULL
;
2161 if (keyboard_layout
)
2162 vs
->kbd_layout
= init_keyboard_layout(keyboard_layout
);
2164 vs
->kbd_layout
= init_keyboard_layout("en-us");
2166 if (!vs
->kbd_layout
)
2169 vs
->timer
= qemu_new_timer(rt_clock
, vnc_update_client
, vs
);
2171 dcl
->dpy_update
= vnc_dpy_update
;
2172 dcl
->dpy_resize
= vnc_dpy_resize
;
2173 dcl
->dpy_setdata
= vnc_dpy_setdata
;
2174 dcl
->dpy_refresh
= NULL
;
2175 register_displaychangelistener(ds
, dcl
);
2177 vs
->as
.freq
= 44100;
2178 vs
->as
.nchannels
= 2;
2179 vs
->as
.fmt
= AUD_FMT_S16
;
2180 vs
->as
.endianness
= 0;
2183 #ifdef CONFIG_VNC_TLS
2184 static int vnc_set_x509_credential(VncState
*vs
,
2185 const char *certdir
,
2186 const char *filename
,
2197 if (!(*cred
= qemu_malloc(strlen(certdir
) + strlen(filename
) + 2)))
2200 strcpy(*cred
, certdir
);
2202 strcat(*cred
, filename
);
2204 VNC_DEBUG("Check %s\n", *cred
);
2205 if (stat(*cred
, &sb
) < 0) {
2208 if (ignoreMissing
&& errno
== ENOENT
)
2216 static int vnc_set_x509_credential_dir(VncState
*vs
,
2217 const char *certdir
)
2219 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CERT_FILE
, &vs
->x509cacert
, 0) < 0)
2221 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CRL_FILE
, &vs
->x509cacrl
, 1) < 0)
2223 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_CERT_FILE
, &vs
->x509cert
, 0) < 0)
2225 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_KEY_FILE
, &vs
->x509key
, 0) < 0)
2231 qemu_free(vs
->x509cacert
);
2232 qemu_free(vs
->x509cacrl
);
2233 qemu_free(vs
->x509cert
);
2234 qemu_free(vs
->x509key
);
2235 vs
->x509cacert
= vs
->x509cacrl
= vs
->x509cert
= vs
->x509key
= NULL
;
2238 #endif /* CONFIG_VNC_TLS */
2240 void vnc_display_close(DisplayState
*ds
)
2242 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2245 qemu_free(vs
->display
);
2248 if (vs
->lsock
!= -1) {
2249 qemu_set_fd_handler2(vs
->lsock
, NULL
, NULL
, NULL
, NULL
);
2253 if (vs
->csock
!= -1) {
2254 qemu_set_fd_handler2(vs
->csock
, NULL
, NULL
, NULL
, NULL
);
2255 closesocket(vs
->csock
);
2257 buffer_reset(&vs
->input
);
2258 buffer_reset(&vs
->output
);
2259 vs
->need_update
= 0;
2260 #ifdef CONFIG_VNC_TLS
2261 if (vs
->tls_session
) {
2262 gnutls_deinit(vs
->tls_session
);
2263 vs
->tls_session
= NULL
;
2265 vs
->wiremode
= VNC_WIREMODE_CLEAR
;
2266 #endif /* CONFIG_VNC_TLS */
2268 vs
->auth
= VNC_AUTH_INVALID
;
2269 #ifdef CONFIG_VNC_TLS
2270 vs
->subauth
= VNC_AUTH_INVALID
;
2276 int vnc_display_password(DisplayState
*ds
, const char *password
)
2278 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2281 qemu_free(vs
->password
);
2282 vs
->password
= NULL
;
2284 if (password
&& password
[0]) {
2285 if (!(vs
->password
= qemu_strdup(password
)))
2292 int vnc_display_open(DisplayState
*ds
, const char *display
)
2294 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2295 const char *options
;
2299 #ifdef CONFIG_VNC_TLS
2300 int tls
= 0, x509
= 0;
2303 vnc_display_close(ds
);
2304 if (strcmp(display
, "none") == 0)
2307 if (!(vs
->display
= strdup(display
)))
2311 while ((options
= strchr(options
, ','))) {
2313 if (strncmp(options
, "password", 8) == 0) {
2314 password
= 1; /* Require password auth */
2315 } else if (strncmp(options
, "reverse", 7) == 0) {
2317 } else if (strncmp(options
, "to=", 3) == 0) {
2318 to_port
= atoi(options
+3) + 5900;
2319 #ifdef CONFIG_VNC_TLS
2320 } else if (strncmp(options
, "tls", 3) == 0) {
2321 tls
= 1; /* Require TLS */
2322 } else if (strncmp(options
, "x509", 4) == 0) {
2324 x509
= 1; /* Require x509 certificates */
2325 if (strncmp(options
, "x509verify", 10) == 0)
2326 vs
->x509verify
= 1; /* ...and verify client certs */
2328 /* Now check for 'x509=/some/path' postfix
2329 * and use that to setup x509 certificate/key paths */
2330 start
= strchr(options
, '=');
2331 end
= strchr(options
, ',');
2332 if (start
&& (!end
|| (start
< end
))) {
2333 int len
= end
? end
-(start
+1) : strlen(start
+1);
2334 char *path
= qemu_strndup(start
+ 1, len
);
2336 VNC_DEBUG("Trying certificate path '%s'\n", path
);
2337 if (vnc_set_x509_credential_dir(vs
, path
) < 0) {
2338 fprintf(stderr
, "Failed to find x509 certificates/keys in %s\n", path
);
2340 qemu_free(vs
->display
);
2346 fprintf(stderr
, "No certificate path provided\n");
2347 qemu_free(vs
->display
);
2356 #ifdef CONFIG_VNC_TLS
2358 vs
->auth
= VNC_AUTH_VENCRYPT
;
2360 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2361 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
2363 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2364 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
2368 VNC_DEBUG("Initializing VNC server with password auth\n");
2369 vs
->auth
= VNC_AUTH_VNC
;
2370 #ifdef CONFIG_VNC_TLS
2371 vs
->subauth
= VNC_AUTH_INVALID
;
2375 #ifdef CONFIG_VNC_TLS
2377 vs
->auth
= VNC_AUTH_VENCRYPT
;
2379 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2380 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
2382 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2383 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
2387 VNC_DEBUG("Initializing VNC server with no auth\n");
2388 vs
->auth
= VNC_AUTH_NONE
;
2389 #ifdef CONFIG_VNC_TLS
2390 vs
->subauth
= VNC_AUTH_INVALID
;
2396 /* connect to viewer */
2397 if (strncmp(display
, "unix:", 5) == 0)
2398 vs
->lsock
= unix_connect(display
+5);
2400 vs
->lsock
= inet_connect(display
, SOCK_STREAM
);
2401 if (-1 == vs
->lsock
) {
2406 vs
->csock
= vs
->lsock
;
2413 /* listen for connects */
2415 dpy
= qemu_malloc(256);
2416 if (strncmp(display
, "unix:", 5) == 0) {
2417 pstrcpy(dpy
, 256, "unix:");
2418 vs
->lsock
= unix_listen(display
+5, dpy
+5, 256-5);
2420 vs
->lsock
= inet_listen(display
, dpy
, 256, SOCK_STREAM
, 5900);
2422 if (-1 == vs
->lsock
) {
2431 return qemu_set_fd_handler2(vs
->lsock
, vnc_listen_poll
, vnc_listen_read
, NULL
, vs
);