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)
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
,
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
94 VNC_AUTH_VENCRYPT
= 19
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 */
129 uint32_t dirty_row
[VNC_MAX_HEIGHT
][VNC_DIRTY_WORDS
];
131 int depth
; /* internal VNC frame buffer byte per pixel */
134 int has_pointer_type_change
;
146 #ifdef CONFIG_VNC_TLS
155 char challenge
[VNC_AUTH_CHALLENGE_SIZE
];
157 #ifdef CONFIG_VNC_TLS
159 gnutls_session_t tls_session
;
164 kbd_layout_t
*kbd_layout
;
165 /* current output mode information */
166 VncWritePixels
*write_pixels
;
167 VncSendHextileTile
*send_hextile_tile
;
168 int pix_bpp
, pix_big_endian
;
169 int client_red_shift
, client_red_max
, server_red_shift
, server_red_max
;
170 int client_green_shift
, client_green_max
, server_green_shift
, server_green_max
;
171 int client_blue_shift
, client_blue_max
, server_blue_shift
, server_blue_max
;
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
->width
);
275 y
= MIN(y
, vs
->height
);
276 w
= MIN(x
+ w
, vs
->width
) - x
;
277 h
= MIN(h
, vs
->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
->depth
)
308 console_color_init(ds
);
310 size_changed
= ds_get_width(ds
) != vs
->width
|| ds_get_height(ds
) != vs
->height
;
312 vs
->width
= ds_get_width(ds
);
313 vs
->height
= ds_get_height(ds
);
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
->server_red_shift
) & vs
->server_red_max
) * (vs
->client_red_max
+ 1) /
339 (vs
->server_red_max
+ 1);
340 g
= ((v
>> vs
->server_green_shift
) & vs
->server_green_max
) * (vs
->client_green_max
+ 1) /
341 (vs
->server_green_max
+ 1);
342 b
= ((v
>> vs
->server_blue_shift
) & vs
->server_blue_max
) * (vs
->client_blue_max
+ 1) /
343 (vs
->server_blue_max
+ 1);
344 v
= (r
<< vs
->client_red_shift
) |
345 (g
<< vs
->client_green_shift
) |
346 (b
<< vs
->client_blue_shift
);
347 switch(vs
->pix_bpp
) {
352 if (vs
->pix_big_endian
) {
362 if (vs
->pix_big_endian
) {
377 static void vnc_write_pixels_generic(VncState
*vs
, void *pixels1
, int size
)
381 if (vs
->depth
== 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
->pix_bpp
);
389 } else if (vs
->depth
== 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
->pix_bpp
);
397 } else if (vs
->depth
== 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
->pix_bpp
);
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
* vs
->depth
;
418 for (i
= 0; i
< h
; i
++) {
419 vs
->write_pixels(vs
, row
, w
* vs
->depth
);
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
->depth
);
469 last_bg
= (uint8_t *) malloc(vs
->depth
);
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
->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
, (vs
->width
/ 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
< vs
->height
; 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 * vs
->depth
) == 0) {
554 vnc_clear_bit(vs
->dirty_row
[y
], (x
/ 16));
557 memcpy(old_ptr
, ptr
, 16 * vs
->depth
);
560 ptr
+= 16 * vs
->depth
;
561 old_ptr
+= 16 * vs
->depth
;
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
->height
; y
++) {
584 for (x
= 0; x
< vs
->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
) * vs
->depth
);
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_format(VncState
*vs
,
1236 int bits_per_pixel
, int depth
,
1237 int big_endian_flag
, int true_color_flag
,
1238 int red_max
, int green_max
, int blue_max
,
1239 int red_shift
, int green_shift
, int blue_shift
)
1241 int host_big_endian_flag
;
1243 #ifdef WORDS_BIGENDIAN
1244 host_big_endian_flag
= 1;
1246 host_big_endian_flag
= 0;
1248 if (!true_color_flag
) {
1250 vnc_client_error(vs
);
1253 if (bits_per_pixel
== 32 &&
1254 bits_per_pixel
== vs
->depth
* 8 &&
1255 host_big_endian_flag
== big_endian_flag
&&
1256 red_max
== 0xff && green_max
== 0xff && blue_max
== 0xff &&
1257 red_shift
== 16 && green_shift
== 8 && blue_shift
== 0) {
1259 vs
->write_pixels
= vnc_write_pixels_copy
;
1260 vs
->send_hextile_tile
= send_hextile_tile_32
;
1262 if (bits_per_pixel
== 16 &&
1263 bits_per_pixel
== vs
->depth
* 8 &&
1264 host_big_endian_flag
== big_endian_flag
&&
1265 red_max
== 31 && green_max
== 63 && blue_max
== 31 &&
1266 red_shift
== 11 && green_shift
== 5 && blue_shift
== 0) {
1268 vs
->write_pixels
= vnc_write_pixels_copy
;
1269 vs
->send_hextile_tile
= send_hextile_tile_16
;
1271 if (bits_per_pixel
== 8 &&
1272 bits_per_pixel
== vs
->depth
* 8 &&
1273 red_max
== 7 && green_max
== 7 && blue_max
== 3 &&
1274 red_shift
== 5 && green_shift
== 2 && blue_shift
== 0) {
1276 vs
->write_pixels
= vnc_write_pixels_copy
;
1277 vs
->send_hextile_tile
= send_hextile_tile_8
;
1280 /* generic and slower case */
1281 if (bits_per_pixel
!= 8 &&
1282 bits_per_pixel
!= 16 &&
1283 bits_per_pixel
!= 32)
1285 if (vs
->depth
== 4) {
1286 vs
->send_hextile_tile
= send_hextile_tile_generic_32
;
1287 } else if (vs
->depth
== 2) {
1288 vs
->send_hextile_tile
= send_hextile_tile_generic_16
;
1290 vs
->send_hextile_tile
= send_hextile_tile_generic_8
;
1293 vs
->pix_big_endian
= big_endian_flag
;
1294 vs
->write_pixels
= vnc_write_pixels_generic
;
1297 vs
->client_red_shift
= red_shift
;
1298 vs
->client_red_max
= red_max
;
1299 vs
->client_green_shift
= green_shift
;
1300 vs
->client_green_max
= green_max
;
1301 vs
->client_blue_shift
= blue_shift
;
1302 vs
->client_blue_max
= blue_max
;
1303 vs
->pix_bpp
= bits_per_pixel
/ 8;
1305 vga_hw_invalidate();
1309 static void pixel_format_message (VncState
*vs
) {
1310 char pad
[3] = { 0, 0, 0 };
1312 vnc_write_u8(vs
, vs
->depth
* 8); /* bits-per-pixel */
1313 if (vs
->depth
== 4) vnc_write_u8(vs
, 24); /* depth */
1314 else vnc_write_u8(vs
, vs
->depth
* 8); /* depth */
1316 #ifdef WORDS_BIGENDIAN
1317 vnc_write_u8(vs
, 1); /* big-endian-flag */
1319 vnc_write_u8(vs
, 0); /* big-endian-flag */
1321 vnc_write_u8(vs
, 1); /* true-color-flag */
1322 if (vs
->depth
== 4) {
1323 vnc_write_u16(vs
, 0xFF); /* red-max */
1324 vnc_write_u16(vs
, 0xFF); /* green-max */
1325 vnc_write_u16(vs
, 0xFF); /* blue-max */
1326 vnc_write_u8(vs
, 16); /* red-shift */
1327 vnc_write_u8(vs
, 8); /* green-shift */
1328 vnc_write_u8(vs
, 0); /* blue-shift */
1329 vs
->send_hextile_tile
= send_hextile_tile_32
;
1330 } else if (vs
->depth
== 2) {
1331 vnc_write_u16(vs
, 31); /* red-max */
1332 vnc_write_u16(vs
, 63); /* green-max */
1333 vnc_write_u16(vs
, 31); /* blue-max */
1334 vnc_write_u8(vs
, 11); /* red-shift */
1335 vnc_write_u8(vs
, 5); /* green-shift */
1336 vnc_write_u8(vs
, 0); /* blue-shift */
1337 vs
->send_hextile_tile
= send_hextile_tile_16
;
1338 } else if (vs
->depth
== 1) {
1339 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1340 vnc_write_u16(vs
, 7); /* red-max */
1341 vnc_write_u16(vs
, 7); /* green-max */
1342 vnc_write_u16(vs
, 3); /* blue-max */
1343 vnc_write_u8(vs
, 5); /* red-shift */
1344 vnc_write_u8(vs
, 2); /* green-shift */
1345 vnc_write_u8(vs
, 0); /* blue-shift */
1346 vs
->send_hextile_tile
= send_hextile_tile_8
;
1348 vs
->client_red_max
= vs
->server_red_max
;
1349 vs
->client_green_max
= vs
->server_green_max
;
1350 vs
->client_blue_max
= vs
->server_blue_max
;
1351 vs
->client_red_shift
= vs
->server_red_shift
;
1352 vs
->client_green_shift
= vs
->server_green_shift
;
1353 vs
->client_blue_shift
= vs
->server_blue_shift
;
1354 vs
->pix_bpp
= vs
->depth
* 8;
1355 vs
->write_pixels
= vnc_write_pixels_copy
;
1357 vnc_write(vs
, pad
, 3); /* padding */
1360 static void vnc_dpy_setdata(DisplayState
*ds
)
1362 /* We don't have to do anything */
1365 static void vnc_colordepth(DisplayState
*ds
)
1367 int host_big_endian_flag
;
1368 struct VncState
*vs
= ds
->opaque
;
1370 #ifdef WORDS_BIGENDIAN
1371 host_big_endian_flag
= 1;
1373 host_big_endian_flag
= 0;
1376 switch (ds_get_bits_per_pixel(ds
)) {
1379 vs
->server_red_max
= 7;
1380 vs
->server_green_max
= 7;
1381 vs
->server_blue_max
= 3;
1382 vs
->server_red_shift
= 5;
1383 vs
->server_green_shift
= 2;
1384 vs
->server_blue_shift
= 0;
1388 vs
->server_red_max
= 31;
1389 vs
->server_green_max
= 63;
1390 vs
->server_blue_max
= 31;
1391 vs
->server_red_shift
= 11;
1392 vs
->server_green_shift
= 5;
1393 vs
->server_blue_shift
= 0;
1397 vs
->server_red_max
= 255;
1398 vs
->server_green_max
= 255;
1399 vs
->server_blue_max
= 255;
1400 vs
->server_red_shift
= 16;
1401 vs
->server_green_shift
= 8;
1402 vs
->server_blue_shift
= 0;
1408 if (vs
->csock
!= -1 && vs
->has_WMVi
) {
1409 /* Sending a WMVi message to notify the client*/
1410 vnc_write_u8(vs
, 0); /* msg id */
1411 vnc_write_u8(vs
, 0);
1412 vnc_write_u16(vs
, 1); /* number of rects */
1413 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(ds
), ds_get_height(ds
), 0x574D5669);
1414 pixel_format_message(vs
);
1417 if (vs
->pix_bpp
== 4 && vs
->depth
== 4 &&
1418 host_big_endian_flag
== vs
->pix_big_endian
&&
1419 vs
->client_red_max
== 0xff && vs
->client_green_max
== 0xff && vs
->client_blue_max
== 0xff &&
1420 vs
->client_red_shift
== 16 && vs
->client_green_shift
== 8 && vs
->client_blue_shift
== 0) {
1421 vs
->write_pixels
= vnc_write_pixels_copy
;
1422 vs
->send_hextile_tile
= send_hextile_tile_32
;
1423 } else if (vs
->pix_bpp
== 2 && vs
->depth
== 2 &&
1424 host_big_endian_flag
== vs
->pix_big_endian
&&
1425 vs
->client_red_max
== 31 && vs
->client_green_max
== 63 && vs
->client_blue_max
== 31 &&
1426 vs
->client_red_shift
== 11 && vs
->client_green_shift
== 5 && vs
->client_blue_shift
== 0) {
1427 vs
->write_pixels
= vnc_write_pixels_copy
;
1428 vs
->send_hextile_tile
= send_hextile_tile_16
;
1429 } else if (vs
->pix_bpp
== 1 && vs
->depth
== 1 &&
1430 host_big_endian_flag
== vs
->pix_big_endian
&&
1431 vs
->client_red_max
== 7 && vs
->client_green_max
== 7 && vs
->client_blue_max
== 3 &&
1432 vs
->client_red_shift
== 5 && vs
->client_green_shift
== 2 && vs
->client_blue_shift
== 0) {
1433 vs
->write_pixels
= vnc_write_pixels_copy
;
1434 vs
->send_hextile_tile
= send_hextile_tile_8
;
1436 if (vs
->depth
== 4) {
1437 vs
->send_hextile_tile
= send_hextile_tile_generic_32
;
1438 } else if (vs
->depth
== 2) {
1439 vs
->send_hextile_tile
= send_hextile_tile_generic_16
;
1441 vs
->send_hextile_tile
= send_hextile_tile_generic_8
;
1443 vs
->write_pixels
= vnc_write_pixels_generic
;
1448 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
1458 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
1459 read_u8(data
, 6), read_u8(data
, 7),
1460 read_u16(data
, 8), read_u16(data
, 10),
1461 read_u16(data
, 12), read_u8(data
, 14),
1462 read_u8(data
, 15), read_u8(data
, 16));
1469 limit
= read_u16(data
, 2);
1471 return 4 + (limit
* 4);
1473 limit
= read_u16(data
, 2);
1475 for (i
= 0; i
< limit
; i
++) {
1476 int32_t val
= read_s32(data
, 4 + (i
* 4));
1477 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
1480 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
1486 framebuffer_update_request(vs
,
1487 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
1488 read_u16(data
, 6), read_u16(data
, 8));
1494 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
1500 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
1507 uint32_t dlen
= read_u32(data
, 4);
1512 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
1518 switch (read_u8(data
, 1)) {
1523 ext_key_event(vs
, read_u16(data
, 2),
1524 read_u32(data
, 4), read_u32(data
, 8));
1530 switch (read_u16 (data
, 2)) {
1540 switch (read_u8(data
, 4)) {
1541 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
1542 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
1543 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
1544 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
1545 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
1546 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
1548 printf("Invalid audio format %d\n", read_u8(data
, 4));
1549 vnc_client_error(vs
);
1552 vs
->as
.nchannels
= read_u8(data
, 5);
1553 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
1554 printf("Invalid audio channel coount %d\n",
1556 vnc_client_error(vs
);
1559 vs
->as
.freq
= read_u32(data
, 6);
1562 printf ("Invalid audio message %d\n", read_u8(data
, 4));
1563 vnc_client_error(vs
);
1569 printf("Msg: %d\n", read_u16(data
, 0));
1570 vnc_client_error(vs
);
1575 printf("Msg: %d\n", data
[0]);
1576 vnc_client_error(vs
);
1580 vnc_read_when(vs
, protocol_client_msg
, 1);
1584 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
1589 vs
->width
= ds_get_width(vs
->ds
);
1590 vs
->height
= ds_get_height(vs
->ds
);
1591 vnc_write_u16(vs
, ds_get_width(vs
->ds
));
1592 vnc_write_u16(vs
, ds_get_height(vs
->ds
));
1594 pixel_format_message(vs
);
1597 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
1599 size
= snprintf(buf
, sizeof(buf
), "QEMU");
1601 vnc_write_u32(vs
, size
);
1602 vnc_write(vs
, buf
, size
);
1605 vnc_read_when(vs
, protocol_client_msg
, 1);
1610 static void make_challenge(VncState
*vs
)
1614 srand(time(NULL
)+getpid()+getpid()*987654+rand());
1616 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
1617 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
1620 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
1622 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
1624 unsigned char key
[8];
1626 if (!vs
->password
|| !vs
->password
[0]) {
1627 VNC_DEBUG("No password configured on server");
1628 vnc_write_u32(vs
, 1); /* Reject auth */
1629 if (vs
->minor
>= 8) {
1630 static const char err
[] = "Authentication failed";
1631 vnc_write_u32(vs
, sizeof(err
));
1632 vnc_write(vs
, err
, sizeof(err
));
1635 vnc_client_error(vs
);
1639 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
1641 /* Calculate the expected challenge response */
1642 pwlen
= strlen(vs
->password
);
1643 for (i
=0; i
<sizeof(key
); i
++)
1644 key
[i
] = i
<pwlen
? vs
->password
[i
] : 0;
1646 for (j
= 0; j
< VNC_AUTH_CHALLENGE_SIZE
; j
+= 8)
1647 des(response
+j
, response
+j
);
1649 /* Compare expected vs actual challenge response */
1650 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
1651 VNC_DEBUG("Client challenge reponse did not match\n");
1652 vnc_write_u32(vs
, 1); /* Reject auth */
1653 if (vs
->minor
>= 8) {
1654 static const char err
[] = "Authentication failed";
1655 vnc_write_u32(vs
, sizeof(err
));
1656 vnc_write(vs
, err
, sizeof(err
));
1659 vnc_client_error(vs
);
1661 VNC_DEBUG("Accepting VNC challenge response\n");
1662 vnc_write_u32(vs
, 0); /* Accept auth */
1665 vnc_read_when(vs
, protocol_client_init
, 1);
1670 static int start_auth_vnc(VncState
*vs
)
1673 /* Send client a 'random' challenge */
1674 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
1677 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
1682 #ifdef CONFIG_VNC_TLS
1683 #define DH_BITS 1024
1684 static gnutls_dh_params_t dh_params
;
1686 static int vnc_tls_initialize(void)
1688 static int tlsinitialized
= 0;
1693 if (gnutls_global_init () < 0)
1696 /* XXX ought to re-generate diffie-hellmen params periodically */
1697 if (gnutls_dh_params_init (&dh_params
) < 0)
1699 if (gnutls_dh_params_generate2 (dh_params
, DH_BITS
) < 0)
1702 #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
1703 gnutls_global_set_log_level(10);
1704 gnutls_global_set_log_function(vnc_debug_gnutls_log
);
1712 static gnutls_anon_server_credentials
vnc_tls_initialize_anon_cred(void)
1714 gnutls_anon_server_credentials anon_cred
;
1717 if ((ret
= gnutls_anon_allocate_server_credentials(&anon_cred
)) < 0) {
1718 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1722 gnutls_anon_set_server_dh_params(anon_cred
, dh_params
);
1728 static gnutls_certificate_credentials_t
vnc_tls_initialize_x509_cred(VncState
*vs
)
1730 gnutls_certificate_credentials_t x509_cred
;
1733 if (!vs
->x509cacert
) {
1734 VNC_DEBUG("No CA x509 certificate specified\n");
1737 if (!vs
->x509cert
) {
1738 VNC_DEBUG("No server x509 certificate specified\n");
1742 VNC_DEBUG("No server private key specified\n");
1746 if ((ret
= gnutls_certificate_allocate_credentials(&x509_cred
)) < 0) {
1747 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1750 if ((ret
= gnutls_certificate_set_x509_trust_file(x509_cred
,
1752 GNUTLS_X509_FMT_PEM
)) < 0) {
1753 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret
));
1754 gnutls_certificate_free_credentials(x509_cred
);
1758 if ((ret
= gnutls_certificate_set_x509_key_file (x509_cred
,
1761 GNUTLS_X509_FMT_PEM
)) < 0) {
1762 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret
));
1763 gnutls_certificate_free_credentials(x509_cred
);
1767 if (vs
->x509cacrl
) {
1768 if ((ret
= gnutls_certificate_set_x509_crl_file(x509_cred
,
1770 GNUTLS_X509_FMT_PEM
)) < 0) {
1771 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret
));
1772 gnutls_certificate_free_credentials(x509_cred
);
1777 gnutls_certificate_set_dh_params (x509_cred
, dh_params
);
1782 static int vnc_validate_certificate(struct VncState
*vs
)
1785 unsigned int status
;
1786 const gnutls_datum_t
*certs
;
1787 unsigned int nCerts
, i
;
1790 VNC_DEBUG("Validating client certificate\n");
1791 if ((ret
= gnutls_certificate_verify_peers2 (vs
->tls_session
, &status
)) < 0) {
1792 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret
));
1796 if ((now
= time(NULL
)) == ((time_t)-1)) {
1801 if (status
& GNUTLS_CERT_INVALID
)
1802 VNC_DEBUG("The certificate is not trusted.\n");
1804 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
1805 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1807 if (status
& GNUTLS_CERT_REVOKED
)
1808 VNC_DEBUG("The certificate has been revoked.\n");
1810 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1811 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1815 VNC_DEBUG("Certificate is valid!\n");
1818 /* Only support x509 for now */
1819 if (gnutls_certificate_type_get(vs
->tls_session
) != GNUTLS_CRT_X509
)
1822 if (!(certs
= gnutls_certificate_get_peers(vs
->tls_session
, &nCerts
)))
1825 for (i
= 0 ; i
< nCerts
; i
++) {
1826 gnutls_x509_crt_t cert
;
1827 VNC_DEBUG ("Checking certificate chain %d\n", i
);
1828 if (gnutls_x509_crt_init (&cert
) < 0)
1831 if (gnutls_x509_crt_import(cert
, &certs
[i
], GNUTLS_X509_FMT_DER
) < 0) {
1832 gnutls_x509_crt_deinit (cert
);
1836 if (gnutls_x509_crt_get_expiration_time (cert
) < now
) {
1837 VNC_DEBUG("The certificate has expired\n");
1838 gnutls_x509_crt_deinit (cert
);
1842 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1843 VNC_DEBUG("The certificate is not yet activated\n");
1844 gnutls_x509_crt_deinit (cert
);
1848 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1849 VNC_DEBUG("The certificate is not yet activated\n");
1850 gnutls_x509_crt_deinit (cert
);
1854 gnutls_x509_crt_deinit (cert
);
1861 static int start_auth_vencrypt_subauth(VncState
*vs
)
1863 switch (vs
->subauth
) {
1864 case VNC_AUTH_VENCRYPT_TLSNONE
:
1865 case VNC_AUTH_VENCRYPT_X509NONE
:
1866 VNC_DEBUG("Accept TLS auth none\n");
1867 vnc_write_u32(vs
, 0); /* Accept auth completion */
1868 vnc_read_when(vs
, protocol_client_init
, 1);
1871 case VNC_AUTH_VENCRYPT_TLSVNC
:
1872 case VNC_AUTH_VENCRYPT_X509VNC
:
1873 VNC_DEBUG("Start TLS auth VNC\n");
1874 return start_auth_vnc(vs
);
1876 default: /* Should not be possible, but just in case */
1877 VNC_DEBUG("Reject auth %d\n", vs
->auth
);
1878 vnc_write_u8(vs
, 1);
1879 if (vs
->minor
>= 8) {
1880 static const char err
[] = "Unsupported authentication type";
1881 vnc_write_u32(vs
, sizeof(err
));
1882 vnc_write(vs
, err
, sizeof(err
));
1884 vnc_client_error(vs
);
1890 static void vnc_handshake_io(void *opaque
);
1892 static int vnc_continue_handshake(struct VncState
*vs
) {
1895 if ((ret
= gnutls_handshake(vs
->tls_session
)) < 0) {
1896 if (!gnutls_error_is_fatal(ret
)) {
1897 VNC_DEBUG("Handshake interrupted (blocking)\n");
1898 if (!gnutls_record_get_direction(vs
->tls_session
))
1899 qemu_set_fd_handler(vs
->csock
, vnc_handshake_io
, NULL
, vs
);
1901 qemu_set_fd_handler(vs
->csock
, NULL
, vnc_handshake_io
, vs
);
1904 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret
));
1905 vnc_client_error(vs
);
1909 if (vs
->x509verify
) {
1910 if (vnc_validate_certificate(vs
) < 0) {
1911 VNC_DEBUG("Client verification failed\n");
1912 vnc_client_error(vs
);
1915 VNC_DEBUG("Client verification passed\n");
1919 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1920 vs
->wiremode
= VNC_WIREMODE_TLS
;
1921 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
1923 return start_auth_vencrypt_subauth(vs
);
1926 static void vnc_handshake_io(void *opaque
) {
1927 struct VncState
*vs
= (struct VncState
*)opaque
;
1929 VNC_DEBUG("Handshake IO continue\n");
1930 vnc_continue_handshake(vs
);
1933 #define NEED_X509_AUTH(vs) \
1934 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1935 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1936 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1939 static int vnc_start_tls(struct VncState
*vs
) {
1940 static const int cert_type_priority
[] = { GNUTLS_CRT_X509
, 0 };
1941 static const int protocol_priority
[]= { GNUTLS_TLS1_1
, GNUTLS_TLS1_0
, GNUTLS_SSL3
, 0 };
1942 static const int kx_anon
[] = {GNUTLS_KX_ANON_DH
, 0};
1943 static const int kx_x509
[] = {GNUTLS_KX_DHE_DSS
, GNUTLS_KX_RSA
, GNUTLS_KX_DHE_RSA
, GNUTLS_KX_SRP
, 0};
1945 VNC_DEBUG("Do TLS setup\n");
1946 if (vnc_tls_initialize() < 0) {
1947 VNC_DEBUG("Failed to init TLS\n");
1948 vnc_client_error(vs
);
1951 if (vs
->tls_session
== NULL
) {
1952 if (gnutls_init(&vs
->tls_session
, GNUTLS_SERVER
) < 0) {
1953 vnc_client_error(vs
);
1957 if (gnutls_set_default_priority(vs
->tls_session
) < 0) {
1958 gnutls_deinit(vs
->tls_session
);
1959 vs
->tls_session
= NULL
;
1960 vnc_client_error(vs
);
1964 if (gnutls_kx_set_priority(vs
->tls_session
, NEED_X509_AUTH(vs
) ? kx_x509
: kx_anon
) < 0) {
1965 gnutls_deinit(vs
->tls_session
);
1966 vs
->tls_session
= NULL
;
1967 vnc_client_error(vs
);
1971 if (gnutls_certificate_type_set_priority(vs
->tls_session
, cert_type_priority
) < 0) {
1972 gnutls_deinit(vs
->tls_session
);
1973 vs
->tls_session
= NULL
;
1974 vnc_client_error(vs
);
1978 if (gnutls_protocol_set_priority(vs
->tls_session
, protocol_priority
) < 0) {
1979 gnutls_deinit(vs
->tls_session
);
1980 vs
->tls_session
= NULL
;
1981 vnc_client_error(vs
);
1985 if (NEED_X509_AUTH(vs
)) {
1986 gnutls_certificate_server_credentials x509_cred
= vnc_tls_initialize_x509_cred(vs
);
1988 gnutls_deinit(vs
->tls_session
);
1989 vs
->tls_session
= NULL
;
1990 vnc_client_error(vs
);
1993 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_CERTIFICATE
, x509_cred
) < 0) {
1994 gnutls_deinit(vs
->tls_session
);
1995 vs
->tls_session
= NULL
;
1996 gnutls_certificate_free_credentials(x509_cred
);
1997 vnc_client_error(vs
);
2000 if (vs
->x509verify
) {
2001 VNC_DEBUG("Requesting a client certificate\n");
2002 gnutls_certificate_server_set_request (vs
->tls_session
, GNUTLS_CERT_REQUEST
);
2006 gnutls_anon_server_credentials anon_cred
= vnc_tls_initialize_anon_cred();
2008 gnutls_deinit(vs
->tls_session
);
2009 vs
->tls_session
= NULL
;
2010 vnc_client_error(vs
);
2013 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_ANON
, anon_cred
) < 0) {
2014 gnutls_deinit(vs
->tls_session
);
2015 vs
->tls_session
= NULL
;
2016 gnutls_anon_free_server_credentials(anon_cred
);
2017 vnc_client_error(vs
);
2022 gnutls_transport_set_ptr(vs
->tls_session
, (gnutls_transport_ptr_t
)vs
);
2023 gnutls_transport_set_push_function(vs
->tls_session
, vnc_tls_push
);
2024 gnutls_transport_set_pull_function(vs
->tls_session
, vnc_tls_pull
);
2027 VNC_DEBUG("Start TLS handshake process\n");
2028 return vnc_continue_handshake(vs
);
2031 static int protocol_client_vencrypt_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2033 int auth
= read_u32(data
, 0);
2035 if (auth
!= vs
->subauth
) {
2036 VNC_DEBUG("Rejecting auth %d\n", auth
);
2037 vnc_write_u8(vs
, 0); /* Reject auth */
2039 vnc_client_error(vs
);
2041 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth
);
2042 vnc_write_u8(vs
, 1); /* Accept auth */
2045 if (vnc_start_tls(vs
) < 0) {
2046 VNC_DEBUG("Failed to complete TLS\n");
2050 if (vs
->wiremode
== VNC_WIREMODE_TLS
) {
2051 VNC_DEBUG("Starting VeNCrypt subauth\n");
2052 return start_auth_vencrypt_subauth(vs
);
2054 VNC_DEBUG("TLS handshake blocked\n");
2061 static int protocol_client_vencrypt_init(VncState
*vs
, uint8_t *data
, size_t len
)
2065 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data
[0], (int)data
[1]);
2066 vnc_write_u8(vs
, 1); /* Reject version */
2068 vnc_client_error(vs
);
2070 VNC_DEBUG("Sending allowed auth %d\n", vs
->subauth
);
2071 vnc_write_u8(vs
, 0); /* Accept version */
2072 vnc_write_u8(vs
, 1); /* Number of sub-auths */
2073 vnc_write_u32(vs
, vs
->subauth
); /* The supported auth */
2075 vnc_read_when(vs
, protocol_client_vencrypt_auth
, 4);
2080 static int start_auth_vencrypt(VncState
*vs
)
2082 /* Send VeNCrypt version 0.2 */
2083 vnc_write_u8(vs
, 0);
2084 vnc_write_u8(vs
, 2);
2086 vnc_read_when(vs
, protocol_client_vencrypt_init
, 2);
2089 #endif /* CONFIG_VNC_TLS */
2091 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2093 /* We only advertise 1 auth scheme at a time, so client
2094 * must pick the one we sent. Verify this */
2095 if (data
[0] != vs
->auth
) { /* Reject auth */
2096 VNC_DEBUG("Reject auth %d\n", (int)data
[0]);
2097 vnc_write_u32(vs
, 1);
2098 if (vs
->minor
>= 8) {
2099 static const char err
[] = "Authentication failed";
2100 vnc_write_u32(vs
, sizeof(err
));
2101 vnc_write(vs
, err
, sizeof(err
));
2103 vnc_client_error(vs
);
2104 } else { /* Accept requested auth */
2105 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2108 VNC_DEBUG("Accept auth none\n");
2109 if (vs
->minor
>= 8) {
2110 vnc_write_u32(vs
, 0); /* Accept auth completion */
2113 vnc_read_when(vs
, protocol_client_init
, 1);
2117 VNC_DEBUG("Start VNC auth\n");
2118 return start_auth_vnc(vs
);
2120 #ifdef CONFIG_VNC_TLS
2121 case VNC_AUTH_VENCRYPT
:
2122 VNC_DEBUG("Accept VeNCrypt auth\n");;
2123 return start_auth_vencrypt(vs
);
2124 #endif /* CONFIG_VNC_TLS */
2126 default: /* Should not be possible, but just in case */
2127 VNC_DEBUG("Reject auth %d\n", vs
->auth
);
2128 vnc_write_u8(vs
, 1);
2129 if (vs
->minor
>= 8) {
2130 static const char err
[] = "Authentication failed";
2131 vnc_write_u32(vs
, sizeof(err
));
2132 vnc_write(vs
, err
, sizeof(err
));
2134 vnc_client_error(vs
);
2140 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2144 memcpy(local
, version
, 12);
2147 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2148 VNC_DEBUG("Malformed protocol version %s\n", local
);
2149 vnc_client_error(vs
);
2152 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2153 if (vs
->major
!= 3 ||
2159 VNC_DEBUG("Unsupported client version\n");
2160 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2162 vnc_client_error(vs
);
2165 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2166 * as equivalent to v3.3 by servers
2168 if (vs
->minor
== 4 || vs
->minor
== 5)
2171 if (vs
->minor
== 3) {
2172 if (vs
->auth
== VNC_AUTH_NONE
) {
2173 VNC_DEBUG("Tell client auth none\n");
2174 vnc_write_u32(vs
, vs
->auth
);
2176 vnc_read_when(vs
, protocol_client_init
, 1);
2177 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2178 VNC_DEBUG("Tell client VNC auth\n");
2179 vnc_write_u32(vs
, vs
->auth
);
2183 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2184 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2186 vnc_client_error(vs
);
2189 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2190 vnc_write_u8(vs
, 1); /* num auth */
2191 vnc_write_u8(vs
, vs
->auth
);
2192 vnc_read_when(vs
, protocol_client_auth
, 1);
2199 static void vnc_connect(VncState
*vs
)
2201 VNC_DEBUG("New client on socket %d\n", vs
->csock
);
2203 socket_set_nonblock(vs
->csock
);
2204 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
2205 vnc_write(vs
, "RFB 003.008\n", 12);
2207 vnc_read_when(vs
, protocol_version
, 12);
2208 memset(vs
->old_data
, 0, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
2209 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
2211 vs
->has_hextile
= 0;
2212 dcl
->dpy_copy
= NULL
;
2213 vnc_update_client(vs
);
2217 static void vnc_listen_read(void *opaque
)
2219 VncState
*vs
= opaque
;
2220 struct sockaddr_in addr
;
2221 socklen_t addrlen
= sizeof(addr
);
2226 vs
->csock
= accept(vs
->lsock
, (struct sockaddr
*)&addr
, &addrlen
);
2227 if (vs
->csock
!= -1) {
2232 void vnc_display_init(DisplayState
*ds
)
2236 vs
= qemu_mallocz(sizeof(VncState
));
2237 dcl
= qemu_mallocz(sizeof(DisplayChangeListener
));
2245 vs
->password
= NULL
;
2254 if (keyboard_layout
)
2255 vs
->kbd_layout
= init_keyboard_layout(keyboard_layout
);
2257 vs
->kbd_layout
= init_keyboard_layout("en-us");
2259 if (!vs
->kbd_layout
)
2262 vs
->timer
= qemu_new_timer(rt_clock
, vnc_update_client
, vs
);
2264 dcl
->dpy_update
= vnc_dpy_update
;
2265 dcl
->dpy_resize
= vnc_dpy_resize
;
2266 dcl
->dpy_setdata
= vnc_dpy_setdata
;
2267 dcl
->dpy_refresh
= NULL
;
2268 register_displaychangelistener(ds
, dcl
);
2270 vs
->as
.freq
= 44100;
2271 vs
->as
.nchannels
= 2;
2272 vs
->as
.fmt
= AUD_FMT_S16
;
2273 vs
->as
.endianness
= 0;
2276 #ifdef CONFIG_VNC_TLS
2277 static int vnc_set_x509_credential(VncState
*vs
,
2278 const char *certdir
,
2279 const char *filename
,
2290 if (!(*cred
= qemu_malloc(strlen(certdir
) + strlen(filename
) + 2)))
2293 strcpy(*cred
, certdir
);
2295 strcat(*cred
, filename
);
2297 VNC_DEBUG("Check %s\n", *cred
);
2298 if (stat(*cred
, &sb
) < 0) {
2301 if (ignoreMissing
&& errno
== ENOENT
)
2309 static int vnc_set_x509_credential_dir(VncState
*vs
,
2310 const char *certdir
)
2312 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CERT_FILE
, &vs
->x509cacert
, 0) < 0)
2314 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CRL_FILE
, &vs
->x509cacrl
, 1) < 0)
2316 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_CERT_FILE
, &vs
->x509cert
, 0) < 0)
2318 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_KEY_FILE
, &vs
->x509key
, 0) < 0)
2324 qemu_free(vs
->x509cacert
);
2325 qemu_free(vs
->x509cacrl
);
2326 qemu_free(vs
->x509cert
);
2327 qemu_free(vs
->x509key
);
2328 vs
->x509cacert
= vs
->x509cacrl
= vs
->x509cert
= vs
->x509key
= NULL
;
2331 #endif /* CONFIG_VNC_TLS */
2333 void vnc_display_close(DisplayState
*ds
)
2335 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2338 qemu_free(vs
->display
);
2341 if (vs
->lsock
!= -1) {
2342 qemu_set_fd_handler2(vs
->lsock
, NULL
, NULL
, NULL
, NULL
);
2346 if (vs
->csock
!= -1) {
2347 qemu_set_fd_handler2(vs
->csock
, NULL
, NULL
, NULL
, NULL
);
2348 closesocket(vs
->csock
);
2350 buffer_reset(&vs
->input
);
2351 buffer_reset(&vs
->output
);
2352 vs
->need_update
= 0;
2353 #ifdef CONFIG_VNC_TLS
2354 if (vs
->tls_session
) {
2355 gnutls_deinit(vs
->tls_session
);
2356 vs
->tls_session
= NULL
;
2358 vs
->wiremode
= VNC_WIREMODE_CLEAR
;
2359 #endif /* CONFIG_VNC_TLS */
2361 vs
->auth
= VNC_AUTH_INVALID
;
2362 #ifdef CONFIG_VNC_TLS
2363 vs
->subauth
= VNC_AUTH_INVALID
;
2369 int vnc_display_password(DisplayState
*ds
, const char *password
)
2371 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2374 qemu_free(vs
->password
);
2375 vs
->password
= NULL
;
2377 if (password
&& password
[0]) {
2378 if (!(vs
->password
= qemu_strdup(password
)))
2385 int vnc_display_open(DisplayState
*ds
, const char *display
)
2387 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2388 const char *options
;
2392 #ifdef CONFIG_VNC_TLS
2393 int tls
= 0, x509
= 0;
2396 vnc_display_close(ds
);
2397 if (strcmp(display
, "none") == 0)
2400 if (!(vs
->display
= strdup(display
)))
2404 while ((options
= strchr(options
, ','))) {
2406 if (strncmp(options
, "password", 8) == 0) {
2407 password
= 1; /* Require password auth */
2408 } else if (strncmp(options
, "reverse", 7) == 0) {
2410 } else if (strncmp(options
, "to=", 3) == 0) {
2411 to_port
= atoi(options
+3) + 5900;
2412 #ifdef CONFIG_VNC_TLS
2413 } else if (strncmp(options
, "tls", 3) == 0) {
2414 tls
= 1; /* Require TLS */
2415 } else if (strncmp(options
, "x509", 4) == 0) {
2417 x509
= 1; /* Require x509 certificates */
2418 if (strncmp(options
, "x509verify", 10) == 0)
2419 vs
->x509verify
= 1; /* ...and verify client certs */
2421 /* Now check for 'x509=/some/path' postfix
2422 * and use that to setup x509 certificate/key paths */
2423 start
= strchr(options
, '=');
2424 end
= strchr(options
, ',');
2425 if (start
&& (!end
|| (start
< end
))) {
2426 int len
= end
? end
-(start
+1) : strlen(start
+1);
2427 char *path
= qemu_strndup(start
+ 1, len
);
2429 VNC_DEBUG("Trying certificate path '%s'\n", path
);
2430 if (vnc_set_x509_credential_dir(vs
, path
) < 0) {
2431 fprintf(stderr
, "Failed to find x509 certificates/keys in %s\n", path
);
2433 qemu_free(vs
->display
);
2439 fprintf(stderr
, "No certificate path provided\n");
2440 qemu_free(vs
->display
);
2449 #ifdef CONFIG_VNC_TLS
2451 vs
->auth
= VNC_AUTH_VENCRYPT
;
2453 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2454 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
2456 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2457 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
2461 VNC_DEBUG("Initializing VNC server with password auth\n");
2462 vs
->auth
= VNC_AUTH_VNC
;
2463 #ifdef CONFIG_VNC_TLS
2464 vs
->subauth
= VNC_AUTH_INVALID
;
2468 #ifdef CONFIG_VNC_TLS
2470 vs
->auth
= VNC_AUTH_VENCRYPT
;
2472 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2473 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
2475 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2476 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
2480 VNC_DEBUG("Initializing VNC server with no auth\n");
2481 vs
->auth
= VNC_AUTH_NONE
;
2482 #ifdef CONFIG_VNC_TLS
2483 vs
->subauth
= VNC_AUTH_INVALID
;
2489 /* connect to viewer */
2490 if (strncmp(display
, "unix:", 5) == 0)
2491 vs
->lsock
= unix_connect(display
+5);
2493 vs
->lsock
= inet_connect(display
, SOCK_STREAM
);
2494 if (-1 == vs
->lsock
) {
2499 vs
->csock
= vs
->lsock
;
2506 /* listen for connects */
2508 dpy
= qemu_malloc(256);
2509 if (strncmp(display
, "unix:", 5) == 0) {
2510 pstrcpy(dpy
, 256, "unix:");
2511 vs
->lsock
= unix_listen(display
+5, dpy
+5, 256-5);
2513 vs
->lsock
= inet_listen(display
, dpy
, 256, SOCK_STREAM
, 5900);
2515 if (-1 == vs
->lsock
) {
2524 return qemu_set_fd_handler2(vs
->lsock
, vnc_listen_poll
, vnc_listen_read
, NULL
, vs
);