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 */
184 void do_info_vnc(void)
186 if (vnc_state
== NULL
)
187 term_printf("VNC server disabled\n");
189 term_printf("VNC server active on: ");
190 term_print_filename(vnc_state
->display
);
193 if (vnc_state
->csock
== -1)
194 term_printf("No client connected\n");
196 term_printf("Client connected\n");
201 1) Get the queue working for IO.
202 2) there is some weirdness when using the -S option (the screen is grey
203 and not totally invalidated
204 3) resolutions > 1024
207 static void vnc_write(VncState
*vs
, const void *data
, size_t len
);
208 static void vnc_write_u32(VncState
*vs
, uint32_t value
);
209 static void vnc_write_s32(VncState
*vs
, int32_t value
);
210 static void vnc_write_u16(VncState
*vs
, uint16_t value
);
211 static void vnc_write_u8(VncState
*vs
, uint8_t value
);
212 static void vnc_flush(VncState
*vs
);
213 static void vnc_update_client(void *opaque
);
214 static void vnc_client_read(void *opaque
);
216 static void vnc_colordepth(DisplayState
*ds
, int depth
);
218 static inline void vnc_set_bit(uint32_t *d
, int k
)
220 d
[k
>> 5] |= 1 << (k
& 0x1f);
223 static inline void vnc_clear_bit(uint32_t *d
, int k
)
225 d
[k
>> 5] &= ~(1 << (k
& 0x1f));
228 static inline void vnc_set_bits(uint32_t *d
, int n
, int nb_words
)
238 d
[j
++] = (1 << n
) - 1;
243 static inline int vnc_get_bit(const uint32_t *d
, int k
)
245 return (d
[k
>> 5] >> (k
& 0x1f)) & 1;
248 static inline int vnc_and_bits(const uint32_t *d1
, const uint32_t *d2
,
252 for(i
= 0; i
< nb_words
; i
++) {
253 if ((d1
[i
] & d2
[i
]) != 0)
259 static void vnc_dpy_update(DisplayState
*ds
, int x
, int y
, int w
, int h
)
261 VncState
*vs
= ds
->opaque
;
266 /* round x down to ensure the loop only spans one 16-pixel block per,
267 iteration. otherwise, if (x % 16) != 0, the last iteration may span
268 two 16-pixel blocks but we only mark the first as dirty
273 x
= MIN(x
, vs
->width
);
274 y
= MIN(y
, vs
->height
);
275 w
= MIN(x
+ w
, vs
->width
) - x
;
276 h
= MIN(h
, vs
->height
);
279 for (i
= 0; i
< w
; i
+= 16)
280 vnc_set_bit(vs
->dirty_row
[y
], (x
+ i
) / 16);
283 static void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
286 vnc_write_u16(vs
, x
);
287 vnc_write_u16(vs
, y
);
288 vnc_write_u16(vs
, w
);
289 vnc_write_u16(vs
, h
);
291 vnc_write_s32(vs
, encoding
);
294 static void vnc_dpy_resize(DisplayState
*ds
, int w
, int h
)
297 VncState
*vs
= ds
->opaque
;
299 ds
->data
= qemu_realloc(ds
->data
, w
* h
* vs
->depth
);
300 vs
->old_data
= qemu_realloc(vs
->old_data
, w
* h
* vs
->depth
);
302 if (ds
->data
== NULL
|| vs
->old_data
== NULL
) {
303 fprintf(stderr
, "vnc: memory allocation failed\n");
307 if (ds
->depth
!= vs
->depth
* 8) {
308 ds
->depth
= vs
->depth
* 8;
309 console_color_init(ds
);
311 size_changed
= ds
->width
!= w
|| ds
->height
!= h
;
314 ds
->linesize
= w
* vs
->depth
;
316 vs
->width
= ds
->width
;
317 vs
->height
= ds
->height
;
318 if (vs
->csock
!= -1 && vs
->has_resize
) {
319 vnc_write_u8(vs
, 0); /* msg id */
321 vnc_write_u16(vs
, 1); /* number of rects */
322 vnc_framebuffer_update(vs
, 0, 0, ds
->width
, ds
->height
, -223);
327 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
328 memset(vs
->old_data
, 42, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
332 static void vnc_write_pixels_copy(VncState
*vs
, void *pixels
, int size
)
334 vnc_write(vs
, pixels
, size
);
337 /* slowest but generic code. */
338 static void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
342 r
= ((v
>> vs
->server_red_shift
) & vs
->server_red_max
) * (vs
->client_red_max
+ 1) /
343 (vs
->server_red_max
+ 1);
344 g
= ((v
>> vs
->server_green_shift
) & vs
->server_green_max
) * (vs
->client_green_max
+ 1) /
345 (vs
->server_green_max
+ 1);
346 b
= ((v
>> vs
->server_blue_shift
) & vs
->server_blue_max
) * (vs
->client_blue_max
+ 1) /
347 (vs
->server_blue_max
+ 1);
348 v
= (r
<< vs
->client_red_shift
) |
349 (g
<< vs
->client_green_shift
) |
350 (b
<< vs
->client_blue_shift
);
351 switch(vs
->pix_bpp
) {
356 if (vs
->pix_big_endian
) {
366 if (vs
->pix_big_endian
) {
381 static void vnc_write_pixels_generic(VncState
*vs
, void *pixels1
, int size
)
385 if (vs
->depth
== 4) {
386 uint32_t *pixels
= pixels1
;
389 for(i
= 0; i
< n
; i
++) {
390 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
391 vnc_write(vs
, buf
, vs
->pix_bpp
);
393 } else if (vs
->depth
== 2) {
394 uint16_t *pixels
= pixels1
;
397 for(i
= 0; i
< n
; i
++) {
398 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
399 vnc_write(vs
, buf
, vs
->pix_bpp
);
401 } else if (vs
->depth
== 1) {
402 uint8_t *pixels
= pixels1
;
405 for(i
= 0; i
< n
; i
++) {
406 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
407 vnc_write(vs
, buf
, vs
->pix_bpp
);
410 fprintf(stderr
, "vnc_write_pixels_generic: VncState color depth not supported\n");
414 static void send_framebuffer_update_raw(VncState
*vs
, int x
, int y
, int w
, int h
)
419 vnc_framebuffer_update(vs
, x
, y
, w
, h
, 0);
421 row
= ds_get_data(vs
->ds
) + y
* ds_get_linesize(vs
->ds
) + x
* vs
->depth
;
422 for (i
= 0; i
< h
; i
++) {
423 vs
->write_pixels(vs
, row
, w
* vs
->depth
);
424 row
+= ds_get_linesize(vs
->ds
);
428 static void hextile_enc_cord(uint8_t *ptr
, int x
, int y
, int w
, int h
)
430 ptr
[0] = ((x
& 0x0F) << 4) | (y
& 0x0F);
431 ptr
[1] = (((w
- 1) & 0x0F) << 4) | ((h
- 1) & 0x0F);
435 #include "vnchextile.h"
439 #include "vnchextile.h"
443 #include "vnchextile.h"
448 #include "vnchextile.h"
454 #include "vnchextile.h"
460 #include "vnchextile.h"
464 static void send_framebuffer_update_hextile(VncState
*vs
, int x
, int y
, int w
, int h
)
468 uint8_t *last_fg
, *last_bg
;
470 vnc_framebuffer_update(vs
, x
, y
, w
, h
, 5);
472 last_fg
= (uint8_t *) malloc(vs
->depth
);
473 last_bg
= (uint8_t *) malloc(vs
->depth
);
475 for (j
= y
; j
< (y
+ h
); j
+= 16) {
476 for (i
= x
; i
< (x
+ w
); i
+= 16) {
477 vs
->send_hextile_tile(vs
, i
, j
,
478 MIN(16, x
+ w
- i
), MIN(16, y
+ h
- j
),
479 last_bg
, last_fg
, &has_bg
, &has_fg
);
487 static void send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
490 send_framebuffer_update_hextile(vs
, x
, y
, w
, h
);
492 send_framebuffer_update_raw(vs
, x
, y
, w
, h
);
495 static void vnc_copy(DisplayState
*ds
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
502 int pitch
= ds_get_linesize(ds
);
503 VncState
*vs
= ds
->opaque
;
505 vnc_update_client(vs
);
512 src
= (ds_get_linesize(ds
) * (src_y
+ y
) + vs
->depth
* src_x
);
513 dst
= (ds_get_linesize(ds
) * (dst_y
+ y
) + vs
->depth
* dst_x
);
515 src_row
= ds_get_data(ds
) + src
;
516 dst_row
= ds_get_data(ds
) + dst
;
517 old_row
= vs
->old_data
+ dst
;
519 for (y
= 0; y
< h
; y
++) {
520 memmove(old_row
, src_row
, w
* vs
->depth
);
521 memmove(dst_row
, src_row
, w
* vs
->depth
);
527 vnc_write_u8(vs
, 0); /* msg id */
529 vnc_write_u16(vs
, 1); /* number of rects */
530 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, 1);
531 vnc_write_u16(vs
, src_x
);
532 vnc_write_u16(vs
, src_y
);
536 static int find_dirty_height(VncState
*vs
, int y
, int last_x
, int x
)
540 for (h
= 1; h
< (vs
->height
- y
); h
++) {
542 if (!vnc_get_bit(vs
->dirty_row
[y
+ h
], last_x
))
544 for (tmp_x
= last_x
; tmp_x
< x
; tmp_x
++)
545 vnc_clear_bit(vs
->dirty_row
[y
+ h
], tmp_x
);
551 static void vnc_update_client(void *opaque
)
553 VncState
*vs
= opaque
;
555 if (vs
->need_update
&& vs
->csock
!= -1) {
559 uint32_t width_mask
[VNC_DIRTY_WORDS
];
566 vnc_set_bits(width_mask
, (vs
->width
/ 16), VNC_DIRTY_WORDS
);
568 /* Walk through the dirty map and eliminate tiles that
569 really aren't dirty */
570 row
= ds_get_data(vs
->ds
);
571 old_row
= vs
->old_data
;
573 for (y
= 0; y
< vs
->height
; y
++) {
574 if (vnc_and_bits(vs
->dirty_row
[y
], width_mask
, VNC_DIRTY_WORDS
)) {
580 old_ptr
= (char*)old_row
;
582 for (x
= 0; x
< ds_get_width(vs
->ds
); x
+= 16) {
583 if (memcmp(old_ptr
, ptr
, 16 * vs
->depth
) == 0) {
584 vnc_clear_bit(vs
->dirty_row
[y
], (x
/ 16));
587 memcpy(old_ptr
, ptr
, 16 * vs
->depth
);
590 ptr
+= 16 * vs
->depth
;
591 old_ptr
+= 16 * vs
->depth
;
595 row
+= ds_get_linesize(vs
->ds
);
596 old_row
+= ds_get_linesize(vs
->ds
);
599 if (!has_dirty
&& !vs
->audio_cap
) {
600 qemu_mod_timer(vs
->timer
, qemu_get_clock(rt_clock
) + VNC_REFRESH_INTERVAL
);
604 /* Count rectangles */
606 vnc_write_u8(vs
, 0); /* msg id */
608 saved_offset
= vs
->output
.offset
;
609 vnc_write_u16(vs
, 0);
611 for (y
= 0; y
< vs
->height
; y
++) {
614 for (x
= 0; x
< vs
->width
/ 16; x
++) {
615 if (vnc_get_bit(vs
->dirty_row
[y
], x
)) {
619 vnc_clear_bit(vs
->dirty_row
[y
], x
);
622 int h
= find_dirty_height(vs
, y
, last_x
, x
);
623 send_framebuffer_update(vs
, last_x
* 16, y
, (x
- last_x
) * 16, h
);
630 int h
= find_dirty_height(vs
, y
, last_x
, x
);
631 send_framebuffer_update(vs
, last_x
* 16, y
, (x
- last_x
) * 16, h
);
635 vs
->output
.buffer
[saved_offset
] = (n_rectangles
>> 8) & 0xFF;
636 vs
->output
.buffer
[saved_offset
+ 1] = n_rectangles
& 0xFF;
641 if (vs
->csock
!= -1) {
642 qemu_mod_timer(vs
->timer
, qemu_get_clock(rt_clock
) + VNC_REFRESH_INTERVAL
);
647 static int vnc_listen_poll(void *opaque
)
649 VncState
*vs
= opaque
;
655 static void buffer_reserve(Buffer
*buffer
, size_t len
)
657 if ((buffer
->capacity
- buffer
->offset
) < len
) {
658 buffer
->capacity
+= (len
+ 1024);
659 buffer
->buffer
= qemu_realloc(buffer
->buffer
, buffer
->capacity
);
660 if (buffer
->buffer
== NULL
) {
661 fprintf(stderr
, "vnc: out of memory\n");
667 static int buffer_empty(Buffer
*buffer
)
669 return buffer
->offset
== 0;
672 static uint8_t *buffer_end(Buffer
*buffer
)
674 return buffer
->buffer
+ buffer
->offset
;
677 static void buffer_reset(Buffer
*buffer
)
682 static void buffer_append(Buffer
*buffer
, const void *data
, size_t len
)
684 memcpy(buffer
->buffer
+ buffer
->offset
, data
, len
);
685 buffer
->offset
+= len
;
689 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
691 VncState
*vs
= opaque
;
694 case AUD_CNOTIFY_DISABLE
:
695 vnc_write_u8(vs
, 255);
697 vnc_write_u16(vs
, 0);
701 case AUD_CNOTIFY_ENABLE
:
702 vnc_write_u8(vs
, 255);
704 vnc_write_u16(vs
, 1);
710 static void audio_capture_destroy(void *opaque
)
714 static void audio_capture(void *opaque
, void *buf
, int size
)
716 VncState
*vs
= opaque
;
718 vnc_write_u8(vs
, 255);
720 vnc_write_u16(vs
, 2);
721 vnc_write_u32(vs
, size
);
722 vnc_write(vs
, buf
, size
);
726 static void audio_add(VncState
*vs
)
728 struct audio_capture_ops ops
;
731 term_printf ("audio already running\n");
735 ops
.notify
= audio_capture_notify
;
736 ops
.destroy
= audio_capture_destroy
;
737 ops
.capture
= audio_capture
;
739 vs
->audio_cap
= AUD_add_capture(NULL
, &vs
->as
, &ops
, vs
);
740 if (!vs
->audio_cap
) {
741 term_printf ("Failed to add audio capture\n");
745 static void audio_del(VncState
*vs
)
748 AUD_del_capture(vs
->audio_cap
, vs
);
749 vs
->audio_cap
= NULL
;
753 static int vnc_client_io_error(VncState
*vs
, int ret
, int last_errno
)
755 if (ret
== 0 || ret
== -1) {
757 switch (last_errno
) {
769 VNC_DEBUG("Closing down client sock %d %d\n", ret
, ret
< 0 ? last_errno
: 0);
770 qemu_set_fd_handler2(vs
->csock
, NULL
, NULL
, NULL
, NULL
);
771 closesocket(vs
->csock
);
774 buffer_reset(&vs
->input
);
775 buffer_reset(&vs
->output
);
777 #ifdef CONFIG_VNC_TLS
778 if (vs
->tls_session
) {
779 gnutls_deinit(vs
->tls_session
);
780 vs
->tls_session
= NULL
;
782 vs
->wiremode
= VNC_WIREMODE_CLEAR
;
783 #endif /* CONFIG_VNC_TLS */
790 static void vnc_client_error(VncState
*vs
)
792 vnc_client_io_error(vs
, -1, EINVAL
);
795 static void vnc_client_write(void *opaque
)
798 VncState
*vs
= opaque
;
800 #ifdef CONFIG_VNC_TLS
801 if (vs
->tls_session
) {
802 ret
= gnutls_write(vs
->tls_session
, vs
->output
.buffer
, vs
->output
.offset
);
804 if (ret
== GNUTLS_E_AGAIN
)
811 #endif /* CONFIG_VNC_TLS */
812 ret
= send(vs
->csock
, vs
->output
.buffer
, vs
->output
.offset
, 0);
813 ret
= vnc_client_io_error(vs
, ret
, socket_error());
817 memmove(vs
->output
.buffer
, vs
->output
.buffer
+ ret
, (vs
->output
.offset
- ret
));
818 vs
->output
.offset
-= ret
;
820 if (vs
->output
.offset
== 0) {
821 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
825 static void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
827 vs
->read_handler
= func
;
828 vs
->read_handler_expect
= expecting
;
831 static void vnc_client_read(void *opaque
)
833 VncState
*vs
= opaque
;
836 buffer_reserve(&vs
->input
, 4096);
838 #ifdef CONFIG_VNC_TLS
839 if (vs
->tls_session
) {
840 ret
= gnutls_read(vs
->tls_session
, buffer_end(&vs
->input
), 4096);
842 if (ret
== GNUTLS_E_AGAIN
)
849 #endif /* CONFIG_VNC_TLS */
850 ret
= recv(vs
->csock
, buffer_end(&vs
->input
), 4096, 0);
851 ret
= vnc_client_io_error(vs
, ret
, socket_error());
855 vs
->input
.offset
+= ret
;
857 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
858 size_t len
= vs
->read_handler_expect
;
861 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
866 memmove(vs
->input
.buffer
, vs
->input
.buffer
+ len
, (vs
->input
.offset
- len
));
867 vs
->input
.offset
-= len
;
869 vs
->read_handler_expect
= ret
;
874 static void vnc_write(VncState
*vs
, const void *data
, size_t len
)
876 buffer_reserve(&vs
->output
, len
);
878 if (buffer_empty(&vs
->output
)) {
879 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
882 buffer_append(&vs
->output
, data
, len
);
885 static void vnc_write_s32(VncState
*vs
, int32_t value
)
887 vnc_write_u32(vs
, *(uint32_t *)&value
);
890 static void vnc_write_u32(VncState
*vs
, uint32_t value
)
894 buf
[0] = (value
>> 24) & 0xFF;
895 buf
[1] = (value
>> 16) & 0xFF;
896 buf
[2] = (value
>> 8) & 0xFF;
897 buf
[3] = value
& 0xFF;
899 vnc_write(vs
, buf
, 4);
902 static void vnc_write_u16(VncState
*vs
, uint16_t value
)
906 buf
[0] = (value
>> 8) & 0xFF;
907 buf
[1] = value
& 0xFF;
909 vnc_write(vs
, buf
, 2);
912 static void vnc_write_u8(VncState
*vs
, uint8_t value
)
914 vnc_write(vs
, (char *)&value
, 1);
917 static void vnc_flush(VncState
*vs
)
919 if (vs
->output
.offset
)
920 vnc_client_write(vs
);
923 static uint8_t read_u8(uint8_t *data
, size_t offset
)
928 static uint16_t read_u16(uint8_t *data
, size_t offset
)
930 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
933 static int32_t read_s32(uint8_t *data
, size_t offset
)
935 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
936 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
939 static uint32_t read_u32(uint8_t *data
, size_t offset
)
941 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
942 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
945 #ifdef CONFIG_VNC_TLS
946 static ssize_t
vnc_tls_push(gnutls_transport_ptr_t transport
,
949 struct VncState
*vs
= (struct VncState
*)transport
;
953 ret
= send(vs
->csock
, data
, len
, 0);
963 static ssize_t
vnc_tls_pull(gnutls_transport_ptr_t transport
,
966 struct VncState
*vs
= (struct VncState
*)transport
;
970 ret
= recv(vs
->csock
, data
, len
, 0);
978 #endif /* CONFIG_VNC_TLS */
980 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
984 static void check_pointer_type_change(VncState
*vs
, int absolute
)
986 if (vs
->has_pointer_type_change
&& vs
->absolute
!= absolute
) {
989 vnc_write_u16(vs
, 1);
990 vnc_framebuffer_update(vs
, absolute
, 0,
991 ds_get_width(vs
->ds
), ds_get_height(vs
->ds
), -257);
994 vs
->absolute
= absolute
;
997 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1002 if (button_mask
& 0x01)
1003 buttons
|= MOUSE_EVENT_LBUTTON
;
1004 if (button_mask
& 0x02)
1005 buttons
|= MOUSE_EVENT_MBUTTON
;
1006 if (button_mask
& 0x04)
1007 buttons
|= MOUSE_EVENT_RBUTTON
;
1008 if (button_mask
& 0x08)
1010 if (button_mask
& 0x10)
1014 kbd_mouse_event(x
* 0x7FFF / (ds_get_width(vs
->ds
) - 1),
1015 y
* 0x7FFF / (ds_get_height(vs
->ds
) - 1),
1017 } else if (vs
->has_pointer_type_change
) {
1021 kbd_mouse_event(x
, y
, dz
, buttons
);
1023 if (vs
->last_x
!= -1)
1024 kbd_mouse_event(x
- vs
->last_x
,
1031 check_pointer_type_change(vs
, kbd_mouse_is_absolute());
1034 static void reset_keys(VncState
*vs
)
1037 for(i
= 0; i
< 256; i
++) {
1038 if (vs
->modifiers_state
[i
]) {
1040 kbd_put_keycode(0xe0);
1041 kbd_put_keycode(i
| 0x80);
1042 vs
->modifiers_state
[i
] = 0;
1047 static void press_key(VncState
*vs
, int keysym
)
1049 kbd_put_keycode(keysym2scancode(vs
->kbd_layout
, keysym
) & 0x7f);
1050 kbd_put_keycode(keysym2scancode(vs
->kbd_layout
, keysym
) | 0x80);
1053 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1055 /* QEMU console switch */
1057 case 0x2a: /* Left Shift */
1058 case 0x36: /* Right Shift */
1059 case 0x1d: /* Left CTRL */
1060 case 0x9d: /* Right CTRL */
1061 case 0x38: /* Left ALT */
1062 case 0xb8: /* Right ALT */
1064 vs
->modifiers_state
[keycode
] = 1;
1066 vs
->modifiers_state
[keycode
] = 0;
1068 case 0x02 ... 0x0a: /* '1' to '9' keys */
1069 if (down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1070 /* Reset the modifiers sent to the current console */
1072 console_select(keycode
- 0x02);
1076 case 0x3a: /* CapsLock */
1077 case 0x45: /* NumLock */
1079 vs
->modifiers_state
[keycode
] ^= 1;
1083 if (keycode_is_keypad(vs
->kbd_layout
, keycode
)) {
1084 /* If the numlock state needs to change then simulate an additional
1085 keypress before sending this one. This will happen if the user
1086 toggles numlock away from the VNC window.
1088 if (keysym_is_numlock(vs
->kbd_layout
, sym
& 0xFFFF)) {
1089 if (!vs
->modifiers_state
[0x45]) {
1090 vs
->modifiers_state
[0x45] = 1;
1091 press_key(vs
, 0xff7f);
1094 if (vs
->modifiers_state
[0x45]) {
1095 vs
->modifiers_state
[0x45] = 0;
1096 press_key(vs
, 0xff7f);
1101 if (is_graphic_console()) {
1103 kbd_put_keycode(0xe0);
1105 kbd_put_keycode(keycode
& 0x7f);
1107 kbd_put_keycode(keycode
| 0x80);
1109 /* QEMU console emulation */
1112 case 0x2a: /* Left Shift */
1113 case 0x36: /* Right Shift */
1114 case 0x1d: /* Left CTRL */
1115 case 0x9d: /* Right CTRL */
1116 case 0x38: /* Left ALT */
1117 case 0xb8: /* Right ALT */
1120 kbd_put_keysym(QEMU_KEY_UP
);
1123 kbd_put_keysym(QEMU_KEY_DOWN
);
1126 kbd_put_keysym(QEMU_KEY_LEFT
);
1129 kbd_put_keysym(QEMU_KEY_RIGHT
);
1132 kbd_put_keysym(QEMU_KEY_DELETE
);
1135 kbd_put_keysym(QEMU_KEY_HOME
);
1138 kbd_put_keysym(QEMU_KEY_END
);
1141 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1144 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1147 kbd_put_keysym(sym
);
1154 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1158 if (sym
>= 'A' && sym
<= 'Z' && is_graphic_console())
1159 sym
= sym
- 'A' + 'a';
1161 keycode
= keysym2scancode(vs
->kbd_layout
, sym
& 0xFFFF);
1162 do_key_event(vs
, down
, keycode
, sym
);
1165 static void ext_key_event(VncState
*vs
, int down
,
1166 uint32_t sym
, uint16_t keycode
)
1168 /* if the user specifies a keyboard layout, always use it */
1169 if (keyboard_layout
)
1170 key_event(vs
, down
, sym
);
1172 do_key_event(vs
, down
, keycode
, sym
);
1175 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1176 int x_position
, int y_position
,
1179 if (x_position
> ds_get_width(vs
->ds
))
1180 x_position
= ds_get_width(vs
->ds
);
1181 if (y_position
> ds_get_height(vs
->ds
))
1182 y_position
= ds_get_height(vs
->ds
);
1183 if (x_position
+ w
>= ds_get_width(vs
->ds
))
1184 w
= ds_get_width(vs
->ds
) - x_position
;
1185 if (y_position
+ h
>= ds_get_height(vs
->ds
))
1186 h
= ds_get_height(vs
->ds
) - y_position
;
1189 vs
->need_update
= 1;
1191 char *old_row
= vs
->old_data
+ y_position
* ds_get_linesize(vs
->ds
);
1193 for (i
= 0; i
< h
; i
++) {
1194 vnc_set_bits(vs
->dirty_row
[y_position
+ i
],
1195 (ds_get_width(vs
->ds
) / 16), VNC_DIRTY_WORDS
);
1196 memset(old_row
, 42, ds_get_width(vs
->ds
) * vs
->depth
);
1197 old_row
+= ds_get_linesize(vs
->ds
);
1202 static void send_ext_key_event_ack(VncState
*vs
)
1204 vnc_write_u8(vs
, 0);
1205 vnc_write_u8(vs
, 0);
1206 vnc_write_u16(vs
, 1);
1207 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
), ds_get_height(vs
->ds
), -258);
1211 static void send_ext_audio_ack(VncState
*vs
)
1213 vnc_write_u8(vs
, 0);
1214 vnc_write_u8(vs
, 0);
1215 vnc_write_u16(vs
, 1);
1216 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
), ds_get_height(vs
->ds
), -259);
1220 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1224 vs
->has_hextile
= 0;
1226 vs
->has_pointer_type_change
= 0;
1229 vs
->ds
->dpy_copy
= NULL
;
1231 for (i
= n_encodings
- 1; i
>= 0; i
--) {
1232 switch (encodings
[i
]) {
1234 vs
->has_hextile
= 0;
1236 case 1: /* CopyRect */
1237 vs
->ds
->dpy_copy
= vnc_copy
;
1239 case 5: /* Hextile */
1240 vs
->has_hextile
= 1;
1242 case -223: /* DesktopResize */
1246 vs
->has_pointer_type_change
= 1;
1249 send_ext_key_event_ack(vs
);
1252 send_ext_audio_ack(vs
);
1262 check_pointer_type_change(vs
, kbd_mouse_is_absolute());
1265 static void set_pixel_format(VncState
*vs
,
1266 int bits_per_pixel
, int depth
,
1267 int big_endian_flag
, int true_color_flag
,
1268 int red_max
, int green_max
, int blue_max
,
1269 int red_shift
, int green_shift
, int blue_shift
)
1271 int host_big_endian_flag
;
1273 #ifdef WORDS_BIGENDIAN
1274 host_big_endian_flag
= 1;
1276 host_big_endian_flag
= 0;
1278 if (!true_color_flag
) {
1280 vnc_client_error(vs
);
1283 if (bits_per_pixel
== 32 &&
1284 bits_per_pixel
== vs
->depth
* 8 &&
1285 host_big_endian_flag
== big_endian_flag
&&
1286 red_max
== 0xff && green_max
== 0xff && blue_max
== 0xff &&
1287 red_shift
== 16 && green_shift
== 8 && blue_shift
== 0) {
1289 vs
->write_pixels
= vnc_write_pixels_copy
;
1290 vs
->send_hextile_tile
= send_hextile_tile_32
;
1292 if (bits_per_pixel
== 16 &&
1293 bits_per_pixel
== vs
->depth
* 8 &&
1294 host_big_endian_flag
== big_endian_flag
&&
1295 red_max
== 31 && green_max
== 63 && blue_max
== 31 &&
1296 red_shift
== 11 && green_shift
== 5 && blue_shift
== 0) {
1298 vs
->write_pixels
= vnc_write_pixels_copy
;
1299 vs
->send_hextile_tile
= send_hextile_tile_16
;
1301 if (bits_per_pixel
== 8 &&
1302 bits_per_pixel
== vs
->depth
* 8 &&
1303 red_max
== 7 && green_max
== 7 && blue_max
== 3 &&
1304 red_shift
== 5 && green_shift
== 2 && blue_shift
== 0) {
1306 vs
->write_pixels
= vnc_write_pixels_copy
;
1307 vs
->send_hextile_tile
= send_hextile_tile_8
;
1310 /* generic and slower case */
1311 if (bits_per_pixel
!= 8 &&
1312 bits_per_pixel
!= 16 &&
1313 bits_per_pixel
!= 32)
1315 if (vs
->depth
== 4) {
1316 vs
->send_hextile_tile
= send_hextile_tile_generic_32
;
1317 } else if (vs
->depth
== 2) {
1318 vs
->send_hextile_tile
= send_hextile_tile_generic_16
;
1320 vs
->send_hextile_tile
= send_hextile_tile_generic_8
;
1323 vs
->pix_big_endian
= big_endian_flag
;
1324 vs
->write_pixels
= vnc_write_pixels_generic
;
1327 vs
->client_red_shift
= red_shift
;
1328 vs
->client_red_max
= red_max
;
1329 vs
->client_green_shift
= green_shift
;
1330 vs
->client_green_max
= green_max
;
1331 vs
->client_blue_shift
= blue_shift
;
1332 vs
->client_blue_max
= blue_max
;
1333 vs
->pix_bpp
= bits_per_pixel
/ 8;
1335 vga_hw_invalidate();
1339 static void pixel_format_message (VncState
*vs
) {
1340 char pad
[3] = { 0, 0, 0 };
1342 vnc_write_u8(vs
, vs
->depth
* 8); /* bits-per-pixel */
1343 if (vs
->depth
== 4) vnc_write_u8(vs
, 24); /* depth */
1344 else vnc_write_u8(vs
, vs
->depth
* 8); /* depth */
1346 #ifdef WORDS_BIGENDIAN
1347 vnc_write_u8(vs
, 1); /* big-endian-flag */
1349 vnc_write_u8(vs
, 0); /* big-endian-flag */
1351 vnc_write_u8(vs
, 1); /* true-color-flag */
1352 if (vs
->depth
== 4) {
1353 vnc_write_u16(vs
, 0xFF); /* red-max */
1354 vnc_write_u16(vs
, 0xFF); /* green-max */
1355 vnc_write_u16(vs
, 0xFF); /* blue-max */
1356 vnc_write_u8(vs
, 16); /* red-shift */
1357 vnc_write_u8(vs
, 8); /* green-shift */
1358 vnc_write_u8(vs
, 0); /* blue-shift */
1359 vs
->send_hextile_tile
= send_hextile_tile_32
;
1360 } else if (vs
->depth
== 2) {
1361 vnc_write_u16(vs
, 31); /* red-max */
1362 vnc_write_u16(vs
, 63); /* green-max */
1363 vnc_write_u16(vs
, 31); /* blue-max */
1364 vnc_write_u8(vs
, 11); /* red-shift */
1365 vnc_write_u8(vs
, 5); /* green-shift */
1366 vnc_write_u8(vs
, 0); /* blue-shift */
1367 vs
->send_hextile_tile
= send_hextile_tile_16
;
1368 } else if (vs
->depth
== 1) {
1369 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1370 vnc_write_u16(vs
, 7); /* red-max */
1371 vnc_write_u16(vs
, 7); /* green-max */
1372 vnc_write_u16(vs
, 3); /* blue-max */
1373 vnc_write_u8(vs
, 5); /* red-shift */
1374 vnc_write_u8(vs
, 2); /* green-shift */
1375 vnc_write_u8(vs
, 0); /* blue-shift */
1376 vs
->send_hextile_tile
= send_hextile_tile_8
;
1378 vs
->client_red_max
= vs
->server_red_max
;
1379 vs
->client_green_max
= vs
->server_green_max
;
1380 vs
->client_blue_max
= vs
->server_blue_max
;
1381 vs
->client_red_shift
= vs
->server_red_shift
;
1382 vs
->client_green_shift
= vs
->server_green_shift
;
1383 vs
->client_blue_shift
= vs
->server_blue_shift
;
1384 vs
->pix_bpp
= vs
->depth
* 8;
1385 vs
->write_pixels
= vnc_write_pixels_copy
;
1387 vnc_write(vs
, pad
, 3); /* padding */
1390 static void vnc_colordepth(DisplayState
*ds
, int depth
)
1392 int host_big_endian_flag
;
1393 struct VncState
*vs
= ds
->opaque
;
1397 if (ds
->depth
== 32) return;
1408 #ifdef WORDS_BIGENDIAN
1409 host_big_endian_flag
= 1;
1411 host_big_endian_flag
= 0;
1416 vs
->depth
= depth
/ 8;
1417 vs
->server_red_max
= 7;
1418 vs
->server_green_max
= 7;
1419 vs
->server_blue_max
= 3;
1420 vs
->server_red_shift
= 5;
1421 vs
->server_green_shift
= 2;
1422 vs
->server_blue_shift
= 0;
1425 vs
->depth
= depth
/ 8;
1426 vs
->server_red_max
= 31;
1427 vs
->server_green_max
= 63;
1428 vs
->server_blue_max
= 31;
1429 vs
->server_red_shift
= 11;
1430 vs
->server_green_shift
= 5;
1431 vs
->server_blue_shift
= 0;
1435 vs
->server_red_max
= 255;
1436 vs
->server_green_max
= 255;
1437 vs
->server_blue_max
= 255;
1438 vs
->server_red_shift
= 16;
1439 vs
->server_green_shift
= 8;
1440 vs
->server_blue_shift
= 0;
1446 if (vs
->csock
!= -1 && vs
->has_WMVi
) {
1447 /* Sending a WMVi message to notify the client*/
1448 vnc_write_u8(vs
, 0); /* msg id */
1449 vnc_write_u8(vs
, 0);
1450 vnc_write_u16(vs
, 1); /* number of rects */
1451 vnc_framebuffer_update(vs
, 0, 0, ds
->width
, ds
->height
, 0x574D5669);
1452 pixel_format_message(vs
);
1455 if (vs
->pix_bpp
== 4 && vs
->depth
== 4 &&
1456 host_big_endian_flag
== vs
->pix_big_endian
&&
1457 vs
->client_red_max
== 0xff && vs
->client_green_max
== 0xff && vs
->client_blue_max
== 0xff &&
1458 vs
->client_red_shift
== 16 && vs
->client_green_shift
== 8 && vs
->client_blue_shift
== 0) {
1459 vs
->write_pixels
= vnc_write_pixels_copy
;
1460 vs
->send_hextile_tile
= send_hextile_tile_32
;
1461 } else if (vs
->pix_bpp
== 2 && vs
->depth
== 2 &&
1462 host_big_endian_flag
== vs
->pix_big_endian
&&
1463 vs
->client_red_max
== 31 && vs
->client_green_max
== 63 && vs
->client_blue_max
== 31 &&
1464 vs
->client_red_shift
== 11 && vs
->client_green_shift
== 5 && vs
->client_blue_shift
== 0) {
1465 vs
->write_pixels
= vnc_write_pixels_copy
;
1466 vs
->send_hextile_tile
= send_hextile_tile_16
;
1467 } else if (vs
->pix_bpp
== 1 && vs
->depth
== 1 &&
1468 host_big_endian_flag
== vs
->pix_big_endian
&&
1469 vs
->client_red_max
== 7 && vs
->client_green_max
== 7 && vs
->client_blue_max
== 3 &&
1470 vs
->client_red_shift
== 5 && vs
->client_green_shift
== 2 && vs
->client_blue_shift
== 0) {
1471 vs
->write_pixels
= vnc_write_pixels_copy
;
1472 vs
->send_hextile_tile
= send_hextile_tile_8
;
1474 if (vs
->depth
== 4) {
1475 vs
->send_hextile_tile
= send_hextile_tile_generic_32
;
1476 } else if (vs
->depth
== 2) {
1477 vs
->send_hextile_tile
= send_hextile_tile_generic_16
;
1479 vs
->send_hextile_tile
= send_hextile_tile_generic_8
;
1481 vs
->write_pixels
= vnc_write_pixels_generic
;
1486 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
1496 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
1497 read_u8(data
, 6), read_u8(data
, 7),
1498 read_u16(data
, 8), read_u16(data
, 10),
1499 read_u16(data
, 12), read_u8(data
, 14),
1500 read_u8(data
, 15), read_u8(data
, 16));
1507 return 4 + (read_u16(data
, 2) * 4);
1509 limit
= read_u16(data
, 2);
1510 for (i
= 0; i
< limit
; i
++) {
1511 int32_t val
= read_s32(data
, 4 + (i
* 4));
1512 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
1515 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
1521 framebuffer_update_request(vs
,
1522 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
1523 read_u16(data
, 6), read_u16(data
, 8));
1529 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
1535 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
1542 uint32_t dlen
= read_u32(data
, 4);
1547 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
1553 switch (read_u8(data
, 1)) {
1558 ext_key_event(vs
, read_u16(data
, 2),
1559 read_u32(data
, 4), read_u32(data
, 8));
1565 switch (read_u16 (data
, 2)) {
1575 switch (read_u8(data
, 4)) {
1576 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
1577 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
1578 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
1579 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
1580 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
1581 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
1583 printf("Invalid audio format %d\n", read_u8(data
, 4));
1584 vnc_client_error(vs
);
1587 vs
->as
.nchannels
= read_u8(data
, 5);
1588 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
1589 printf("Invalid audio channel coount %d\n",
1591 vnc_client_error(vs
);
1594 vs
->as
.freq
= read_u32(data
, 6);
1597 printf ("Invalid audio message %d\n", read_u8(data
, 4));
1598 vnc_client_error(vs
);
1604 printf("Msg: %d\n", read_u16(data
, 0));
1605 vnc_client_error(vs
);
1610 printf("Msg: %d\n", data
[0]);
1611 vnc_client_error(vs
);
1615 vnc_read_when(vs
, protocol_client_msg
, 1);
1619 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
1624 vs
->width
= ds_get_width(vs
->ds
);
1625 vs
->height
= ds_get_height(vs
->ds
);
1626 vnc_write_u16(vs
, ds_get_width(vs
->ds
));
1627 vnc_write_u16(vs
, ds_get_height(vs
->ds
));
1629 pixel_format_message(vs
);
1632 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
1634 size
= snprintf(buf
, sizeof(buf
), "QEMU");
1636 vnc_write_u32(vs
, size
);
1637 vnc_write(vs
, buf
, size
);
1640 vnc_read_when(vs
, protocol_client_msg
, 1);
1645 static void make_challenge(VncState
*vs
)
1649 srand(time(NULL
)+getpid()+getpid()*987654+rand());
1651 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
1652 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
1655 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
1657 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
1659 unsigned char key
[8];
1661 if (!vs
->password
|| !vs
->password
[0]) {
1662 VNC_DEBUG("No password configured on server");
1663 vnc_write_u32(vs
, 1); /* Reject auth */
1664 if (vs
->minor
>= 8) {
1665 static const char err
[] = "Authentication failed";
1666 vnc_write_u32(vs
, sizeof(err
));
1667 vnc_write(vs
, err
, sizeof(err
));
1670 vnc_client_error(vs
);
1674 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
1676 /* Calculate the expected challenge response */
1677 pwlen
= strlen(vs
->password
);
1678 for (i
=0; i
<sizeof(key
); i
++)
1679 key
[i
] = i
<pwlen
? vs
->password
[i
] : 0;
1681 for (j
= 0; j
< VNC_AUTH_CHALLENGE_SIZE
; j
+= 8)
1682 des(response
+j
, response
+j
);
1684 /* Compare expected vs actual challenge response */
1685 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
1686 VNC_DEBUG("Client challenge reponse did not match\n");
1687 vnc_write_u32(vs
, 1); /* Reject auth */
1688 if (vs
->minor
>= 8) {
1689 static const char err
[] = "Authentication failed";
1690 vnc_write_u32(vs
, sizeof(err
));
1691 vnc_write(vs
, err
, sizeof(err
));
1694 vnc_client_error(vs
);
1696 VNC_DEBUG("Accepting VNC challenge response\n");
1697 vnc_write_u32(vs
, 0); /* Accept auth */
1700 vnc_read_when(vs
, protocol_client_init
, 1);
1705 static int start_auth_vnc(VncState
*vs
)
1708 /* Send client a 'random' challenge */
1709 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
1712 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
1717 #ifdef CONFIG_VNC_TLS
1718 #define DH_BITS 1024
1719 static gnutls_dh_params_t dh_params
;
1721 static int vnc_tls_initialize(void)
1723 static int tlsinitialized
= 0;
1728 if (gnutls_global_init () < 0)
1731 /* XXX ought to re-generate diffie-hellmen params periodically */
1732 if (gnutls_dh_params_init (&dh_params
) < 0)
1734 if (gnutls_dh_params_generate2 (dh_params
, DH_BITS
) < 0)
1737 #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
1738 gnutls_global_set_log_level(10);
1739 gnutls_global_set_log_function(vnc_debug_gnutls_log
);
1747 static gnutls_anon_server_credentials
vnc_tls_initialize_anon_cred(void)
1749 gnutls_anon_server_credentials anon_cred
;
1752 if ((ret
= gnutls_anon_allocate_server_credentials(&anon_cred
)) < 0) {
1753 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1757 gnutls_anon_set_server_dh_params(anon_cred
, dh_params
);
1763 static gnutls_certificate_credentials_t
vnc_tls_initialize_x509_cred(VncState
*vs
)
1765 gnutls_certificate_credentials_t x509_cred
;
1768 if (!vs
->x509cacert
) {
1769 VNC_DEBUG("No CA x509 certificate specified\n");
1772 if (!vs
->x509cert
) {
1773 VNC_DEBUG("No server x509 certificate specified\n");
1777 VNC_DEBUG("No server private key specified\n");
1781 if ((ret
= gnutls_certificate_allocate_credentials(&x509_cred
)) < 0) {
1782 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1785 if ((ret
= gnutls_certificate_set_x509_trust_file(x509_cred
,
1787 GNUTLS_X509_FMT_PEM
)) < 0) {
1788 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret
));
1789 gnutls_certificate_free_credentials(x509_cred
);
1793 if ((ret
= gnutls_certificate_set_x509_key_file (x509_cred
,
1796 GNUTLS_X509_FMT_PEM
)) < 0) {
1797 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret
));
1798 gnutls_certificate_free_credentials(x509_cred
);
1802 if (vs
->x509cacrl
) {
1803 if ((ret
= gnutls_certificate_set_x509_crl_file(x509_cred
,
1805 GNUTLS_X509_FMT_PEM
)) < 0) {
1806 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret
));
1807 gnutls_certificate_free_credentials(x509_cred
);
1812 gnutls_certificate_set_dh_params (x509_cred
, dh_params
);
1817 static int vnc_validate_certificate(struct VncState
*vs
)
1820 unsigned int status
;
1821 const gnutls_datum_t
*certs
;
1822 unsigned int nCerts
, i
;
1825 VNC_DEBUG("Validating client certificate\n");
1826 if ((ret
= gnutls_certificate_verify_peers2 (vs
->tls_session
, &status
)) < 0) {
1827 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret
));
1831 if ((now
= time(NULL
)) == ((time_t)-1)) {
1836 if (status
& GNUTLS_CERT_INVALID
)
1837 VNC_DEBUG("The certificate is not trusted.\n");
1839 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
1840 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1842 if (status
& GNUTLS_CERT_REVOKED
)
1843 VNC_DEBUG("The certificate has been revoked.\n");
1845 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1846 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1850 VNC_DEBUG("Certificate is valid!\n");
1853 /* Only support x509 for now */
1854 if (gnutls_certificate_type_get(vs
->tls_session
) != GNUTLS_CRT_X509
)
1857 if (!(certs
= gnutls_certificate_get_peers(vs
->tls_session
, &nCerts
)))
1860 for (i
= 0 ; i
< nCerts
; i
++) {
1861 gnutls_x509_crt_t cert
;
1862 VNC_DEBUG ("Checking certificate chain %d\n", i
);
1863 if (gnutls_x509_crt_init (&cert
) < 0)
1866 if (gnutls_x509_crt_import(cert
, &certs
[i
], GNUTLS_X509_FMT_DER
) < 0) {
1867 gnutls_x509_crt_deinit (cert
);
1871 if (gnutls_x509_crt_get_expiration_time (cert
) < now
) {
1872 VNC_DEBUG("The certificate has expired\n");
1873 gnutls_x509_crt_deinit (cert
);
1877 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1878 VNC_DEBUG("The certificate is not yet activated\n");
1879 gnutls_x509_crt_deinit (cert
);
1883 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1884 VNC_DEBUG("The certificate is not yet activated\n");
1885 gnutls_x509_crt_deinit (cert
);
1889 gnutls_x509_crt_deinit (cert
);
1896 static int start_auth_vencrypt_subauth(VncState
*vs
)
1898 switch (vs
->subauth
) {
1899 case VNC_AUTH_VENCRYPT_TLSNONE
:
1900 case VNC_AUTH_VENCRYPT_X509NONE
:
1901 VNC_DEBUG("Accept TLS auth none\n");
1902 vnc_write_u32(vs
, 0); /* Accept auth completion */
1903 vnc_read_when(vs
, protocol_client_init
, 1);
1906 case VNC_AUTH_VENCRYPT_TLSVNC
:
1907 case VNC_AUTH_VENCRYPT_X509VNC
:
1908 VNC_DEBUG("Start TLS auth VNC\n");
1909 return start_auth_vnc(vs
);
1911 default: /* Should not be possible, but just in case */
1912 VNC_DEBUG("Reject auth %d\n", vs
->auth
);
1913 vnc_write_u8(vs
, 1);
1914 if (vs
->minor
>= 8) {
1915 static const char err
[] = "Unsupported authentication type";
1916 vnc_write_u32(vs
, sizeof(err
));
1917 vnc_write(vs
, err
, sizeof(err
));
1919 vnc_client_error(vs
);
1925 static void vnc_handshake_io(void *opaque
);
1927 static int vnc_continue_handshake(struct VncState
*vs
) {
1930 if ((ret
= gnutls_handshake(vs
->tls_session
)) < 0) {
1931 if (!gnutls_error_is_fatal(ret
)) {
1932 VNC_DEBUG("Handshake interrupted (blocking)\n");
1933 if (!gnutls_record_get_direction(vs
->tls_session
))
1934 qemu_set_fd_handler(vs
->csock
, vnc_handshake_io
, NULL
, vs
);
1936 qemu_set_fd_handler(vs
->csock
, NULL
, vnc_handshake_io
, vs
);
1939 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret
));
1940 vnc_client_error(vs
);
1944 if (vs
->x509verify
) {
1945 if (vnc_validate_certificate(vs
) < 0) {
1946 VNC_DEBUG("Client verification failed\n");
1947 vnc_client_error(vs
);
1950 VNC_DEBUG("Client verification passed\n");
1954 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1955 vs
->wiremode
= VNC_WIREMODE_TLS
;
1956 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
1958 return start_auth_vencrypt_subauth(vs
);
1961 static void vnc_handshake_io(void *opaque
) {
1962 struct VncState
*vs
= (struct VncState
*)opaque
;
1964 VNC_DEBUG("Handshake IO continue\n");
1965 vnc_continue_handshake(vs
);
1968 #define NEED_X509_AUTH(vs) \
1969 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1970 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1971 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1974 static int vnc_start_tls(struct VncState
*vs
) {
1975 static const int cert_type_priority
[] = { GNUTLS_CRT_X509
, 0 };
1976 static const int protocol_priority
[]= { GNUTLS_TLS1_1
, GNUTLS_TLS1_0
, GNUTLS_SSL3
, 0 };
1977 static const int kx_anon
[] = {GNUTLS_KX_ANON_DH
, 0};
1978 static const int kx_x509
[] = {GNUTLS_KX_DHE_DSS
, GNUTLS_KX_RSA
, GNUTLS_KX_DHE_RSA
, GNUTLS_KX_SRP
, 0};
1980 VNC_DEBUG("Do TLS setup\n");
1981 if (vnc_tls_initialize() < 0) {
1982 VNC_DEBUG("Failed to init TLS\n");
1983 vnc_client_error(vs
);
1986 if (vs
->tls_session
== NULL
) {
1987 if (gnutls_init(&vs
->tls_session
, GNUTLS_SERVER
) < 0) {
1988 vnc_client_error(vs
);
1992 if (gnutls_set_default_priority(vs
->tls_session
) < 0) {
1993 gnutls_deinit(vs
->tls_session
);
1994 vs
->tls_session
= NULL
;
1995 vnc_client_error(vs
);
1999 if (gnutls_kx_set_priority(vs
->tls_session
, NEED_X509_AUTH(vs
) ? kx_x509
: kx_anon
) < 0) {
2000 gnutls_deinit(vs
->tls_session
);
2001 vs
->tls_session
= NULL
;
2002 vnc_client_error(vs
);
2006 if (gnutls_certificate_type_set_priority(vs
->tls_session
, cert_type_priority
) < 0) {
2007 gnutls_deinit(vs
->tls_session
);
2008 vs
->tls_session
= NULL
;
2009 vnc_client_error(vs
);
2013 if (gnutls_protocol_set_priority(vs
->tls_session
, protocol_priority
) < 0) {
2014 gnutls_deinit(vs
->tls_session
);
2015 vs
->tls_session
= NULL
;
2016 vnc_client_error(vs
);
2020 if (NEED_X509_AUTH(vs
)) {
2021 gnutls_certificate_server_credentials x509_cred
= vnc_tls_initialize_x509_cred(vs
);
2023 gnutls_deinit(vs
->tls_session
);
2024 vs
->tls_session
= NULL
;
2025 vnc_client_error(vs
);
2028 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_CERTIFICATE
, x509_cred
) < 0) {
2029 gnutls_deinit(vs
->tls_session
);
2030 vs
->tls_session
= NULL
;
2031 gnutls_certificate_free_credentials(x509_cred
);
2032 vnc_client_error(vs
);
2035 if (vs
->x509verify
) {
2036 VNC_DEBUG("Requesting a client certificate\n");
2037 gnutls_certificate_server_set_request (vs
->tls_session
, GNUTLS_CERT_REQUEST
);
2041 gnutls_anon_server_credentials anon_cred
= vnc_tls_initialize_anon_cred();
2043 gnutls_deinit(vs
->tls_session
);
2044 vs
->tls_session
= NULL
;
2045 vnc_client_error(vs
);
2048 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_ANON
, anon_cred
) < 0) {
2049 gnutls_deinit(vs
->tls_session
);
2050 vs
->tls_session
= NULL
;
2051 gnutls_anon_free_server_credentials(anon_cred
);
2052 vnc_client_error(vs
);
2057 gnutls_transport_set_ptr(vs
->tls_session
, (gnutls_transport_ptr_t
)vs
);
2058 gnutls_transport_set_push_function(vs
->tls_session
, vnc_tls_push
);
2059 gnutls_transport_set_pull_function(vs
->tls_session
, vnc_tls_pull
);
2062 VNC_DEBUG("Start TLS handshake process\n");
2063 return vnc_continue_handshake(vs
);
2066 static int protocol_client_vencrypt_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2068 int auth
= read_u32(data
, 0);
2070 if (auth
!= vs
->subauth
) {
2071 VNC_DEBUG("Rejecting auth %d\n", auth
);
2072 vnc_write_u8(vs
, 0); /* Reject auth */
2074 vnc_client_error(vs
);
2076 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth
);
2077 vnc_write_u8(vs
, 1); /* Accept auth */
2080 if (vnc_start_tls(vs
) < 0) {
2081 VNC_DEBUG("Failed to complete TLS\n");
2085 if (vs
->wiremode
== VNC_WIREMODE_TLS
) {
2086 VNC_DEBUG("Starting VeNCrypt subauth\n");
2087 return start_auth_vencrypt_subauth(vs
);
2089 VNC_DEBUG("TLS handshake blocked\n");
2096 static int protocol_client_vencrypt_init(VncState
*vs
, uint8_t *data
, size_t len
)
2100 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data
[0], (int)data
[1]);
2101 vnc_write_u8(vs
, 1); /* Reject version */
2103 vnc_client_error(vs
);
2105 VNC_DEBUG("Sending allowed auth %d\n", vs
->subauth
);
2106 vnc_write_u8(vs
, 0); /* Accept version */
2107 vnc_write_u8(vs
, 1); /* Number of sub-auths */
2108 vnc_write_u32(vs
, vs
->subauth
); /* The supported auth */
2110 vnc_read_when(vs
, protocol_client_vencrypt_auth
, 4);
2115 static int start_auth_vencrypt(VncState
*vs
)
2117 /* Send VeNCrypt version 0.2 */
2118 vnc_write_u8(vs
, 0);
2119 vnc_write_u8(vs
, 2);
2121 vnc_read_when(vs
, protocol_client_vencrypt_init
, 2);
2124 #endif /* CONFIG_VNC_TLS */
2126 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2128 /* We only advertise 1 auth scheme at a time, so client
2129 * must pick the one we sent. Verify this */
2130 if (data
[0] != vs
->auth
) { /* Reject auth */
2131 VNC_DEBUG("Reject auth %d\n", (int)data
[0]);
2132 vnc_write_u32(vs
, 1);
2133 if (vs
->minor
>= 8) {
2134 static const char err
[] = "Authentication failed";
2135 vnc_write_u32(vs
, sizeof(err
));
2136 vnc_write(vs
, err
, sizeof(err
));
2138 vnc_client_error(vs
);
2139 } else { /* Accept requested auth */
2140 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2143 VNC_DEBUG("Accept auth none\n");
2144 if (vs
->minor
>= 8) {
2145 vnc_write_u32(vs
, 0); /* Accept auth completion */
2148 vnc_read_when(vs
, protocol_client_init
, 1);
2152 VNC_DEBUG("Start VNC auth\n");
2153 return start_auth_vnc(vs
);
2155 #ifdef CONFIG_VNC_TLS
2156 case VNC_AUTH_VENCRYPT
:
2157 VNC_DEBUG("Accept VeNCrypt auth\n");;
2158 return start_auth_vencrypt(vs
);
2159 #endif /* CONFIG_VNC_TLS */
2161 default: /* Should not be possible, but just in case */
2162 VNC_DEBUG("Reject auth %d\n", vs
->auth
);
2163 vnc_write_u8(vs
, 1);
2164 if (vs
->minor
>= 8) {
2165 static const char err
[] = "Authentication failed";
2166 vnc_write_u32(vs
, sizeof(err
));
2167 vnc_write(vs
, err
, sizeof(err
));
2169 vnc_client_error(vs
);
2175 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2179 memcpy(local
, version
, 12);
2182 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2183 VNC_DEBUG("Malformed protocol version %s\n", local
);
2184 vnc_client_error(vs
);
2187 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2188 if (vs
->major
!= 3 ||
2194 VNC_DEBUG("Unsupported client version\n");
2195 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2197 vnc_client_error(vs
);
2200 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2201 * as equivalent to v3.3 by servers
2203 if (vs
->minor
== 4 || vs
->minor
== 5)
2206 if (vs
->minor
== 3) {
2207 if (vs
->auth
== VNC_AUTH_NONE
) {
2208 VNC_DEBUG("Tell client auth none\n");
2209 vnc_write_u32(vs
, vs
->auth
);
2211 vnc_read_when(vs
, protocol_client_init
, 1);
2212 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2213 VNC_DEBUG("Tell client VNC auth\n");
2214 vnc_write_u32(vs
, vs
->auth
);
2218 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2219 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2221 vnc_client_error(vs
);
2224 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2225 vnc_write_u8(vs
, 1); /* num auth */
2226 vnc_write_u8(vs
, vs
->auth
);
2227 vnc_read_when(vs
, protocol_client_auth
, 1);
2234 static void vnc_connect(VncState
*vs
)
2236 VNC_DEBUG("New client on socket %d\n", vs
->csock
);
2238 socket_set_nonblock(vs
->csock
);
2239 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
2240 vnc_write(vs
, "RFB 003.008\n", 12);
2242 vnc_read_when(vs
, protocol_version
, 12);
2243 memset(vs
->old_data
, 0, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
2244 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
2246 vs
->has_hextile
= 0;
2247 vs
->ds
->dpy_copy
= NULL
;
2248 vnc_update_client(vs
);
2252 static void vnc_listen_read(void *opaque
)
2254 VncState
*vs
= opaque
;
2255 struct sockaddr_in addr
;
2256 socklen_t addrlen
= sizeof(addr
);
2261 vs
->csock
= accept(vs
->lsock
, (struct sockaddr
*)&addr
, &addrlen
);
2262 if (vs
->csock
!= -1) {
2267 void vnc_display_init(DisplayState
*ds
)
2271 vs
= qemu_mallocz(sizeof(VncState
));
2279 vs
->password
= NULL
;
2288 if (keyboard_layout
)
2289 vs
->kbd_layout
= init_keyboard_layout(keyboard_layout
);
2291 vs
->kbd_layout
= init_keyboard_layout("en-us");
2293 if (!vs
->kbd_layout
)
2296 vs
->timer
= qemu_new_timer(rt_clock
, vnc_update_client
, vs
);
2298 vs
->ds
->data
= NULL
;
2299 vs
->ds
->dpy_update
= vnc_dpy_update
;
2300 vs
->ds
->dpy_resize
= vnc_dpy_resize
;
2301 vs
->ds
->dpy_refresh
= NULL
;
2303 vnc_colordepth(vs
->ds
, 32);
2304 vnc_dpy_resize(vs
->ds
, 640, 400);
2306 vs
->as
.freq
= 44100;
2307 vs
->as
.nchannels
= 2;
2308 vs
->as
.fmt
= AUD_FMT_S16
;
2309 vs
->as
.endianness
= 0;
2312 #ifdef CONFIG_VNC_TLS
2313 static int vnc_set_x509_credential(VncState
*vs
,
2314 const char *certdir
,
2315 const char *filename
,
2326 if (!(*cred
= qemu_malloc(strlen(certdir
) + strlen(filename
) + 2)))
2329 strcpy(*cred
, certdir
);
2331 strcat(*cred
, filename
);
2333 VNC_DEBUG("Check %s\n", *cred
);
2334 if (stat(*cred
, &sb
) < 0) {
2337 if (ignoreMissing
&& errno
== ENOENT
)
2345 static int vnc_set_x509_credential_dir(VncState
*vs
,
2346 const char *certdir
)
2348 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CERT_FILE
, &vs
->x509cacert
, 0) < 0)
2350 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CRL_FILE
, &vs
->x509cacrl
, 1) < 0)
2352 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_CERT_FILE
, &vs
->x509cert
, 0) < 0)
2354 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_KEY_FILE
, &vs
->x509key
, 0) < 0)
2360 qemu_free(vs
->x509cacert
);
2361 qemu_free(vs
->x509cacrl
);
2362 qemu_free(vs
->x509cert
);
2363 qemu_free(vs
->x509key
);
2364 vs
->x509cacert
= vs
->x509cacrl
= vs
->x509cert
= vs
->x509key
= NULL
;
2367 #endif /* CONFIG_VNC_TLS */
2369 void vnc_display_close(DisplayState
*ds
)
2371 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2374 qemu_free(vs
->display
);
2377 if (vs
->lsock
!= -1) {
2378 qemu_set_fd_handler2(vs
->lsock
, NULL
, NULL
, NULL
, NULL
);
2382 if (vs
->csock
!= -1) {
2383 qemu_set_fd_handler2(vs
->csock
, NULL
, NULL
, NULL
, NULL
);
2384 closesocket(vs
->csock
);
2386 buffer_reset(&vs
->input
);
2387 buffer_reset(&vs
->output
);
2388 vs
->need_update
= 0;
2389 #ifdef CONFIG_VNC_TLS
2390 if (vs
->tls_session
) {
2391 gnutls_deinit(vs
->tls_session
);
2392 vs
->tls_session
= NULL
;
2394 vs
->wiremode
= VNC_WIREMODE_CLEAR
;
2395 #endif /* CONFIG_VNC_TLS */
2397 vs
->auth
= VNC_AUTH_INVALID
;
2398 #ifdef CONFIG_VNC_TLS
2399 vs
->subauth
= VNC_AUTH_INVALID
;
2405 int vnc_display_password(DisplayState
*ds
, const char *password
)
2407 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2410 qemu_free(vs
->password
);
2411 vs
->password
= NULL
;
2413 if (password
&& password
[0]) {
2414 if (!(vs
->password
= qemu_strdup(password
)))
2421 int vnc_display_open(DisplayState
*ds
, const char *display
)
2423 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2424 const char *options
;
2428 #ifdef CONFIG_VNC_TLS
2429 int tls
= 0, x509
= 0;
2432 vnc_display_close(ds
);
2433 if (strcmp(display
, "none") == 0)
2436 if (!(vs
->display
= strdup(display
)))
2440 while ((options
= strchr(options
, ','))) {
2442 if (strncmp(options
, "password", 8) == 0) {
2443 password
= 1; /* Require password auth */
2444 } else if (strncmp(options
, "reverse", 7) == 0) {
2446 } else if (strncmp(options
, "to=", 3) == 0) {
2447 to_port
= atoi(options
+3) + 5900;
2448 #ifdef CONFIG_VNC_TLS
2449 } else if (strncmp(options
, "tls", 3) == 0) {
2450 tls
= 1; /* Require TLS */
2451 } else if (strncmp(options
, "x509", 4) == 0) {
2453 x509
= 1; /* Require x509 certificates */
2454 if (strncmp(options
, "x509verify", 10) == 0)
2455 vs
->x509verify
= 1; /* ...and verify client certs */
2457 /* Now check for 'x509=/some/path' postfix
2458 * and use that to setup x509 certificate/key paths */
2459 start
= strchr(options
, '=');
2460 end
= strchr(options
, ',');
2461 if (start
&& (!end
|| (start
< end
))) {
2462 int len
= end
? end
-(start
+1) : strlen(start
+1);
2463 char *path
= qemu_strndup(start
+ 1, len
);
2465 VNC_DEBUG("Trying certificate path '%s'\n", path
);
2466 if (vnc_set_x509_credential_dir(vs
, path
) < 0) {
2467 fprintf(stderr
, "Failed to find x509 certificates/keys in %s\n", path
);
2469 qemu_free(vs
->display
);
2475 fprintf(stderr
, "No certificate path provided\n");
2476 qemu_free(vs
->display
);
2485 #ifdef CONFIG_VNC_TLS
2487 vs
->auth
= VNC_AUTH_VENCRYPT
;
2489 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2490 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
2492 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2493 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
2497 VNC_DEBUG("Initializing VNC server with password auth\n");
2498 vs
->auth
= VNC_AUTH_VNC
;
2499 #ifdef CONFIG_VNC_TLS
2500 vs
->subauth
= VNC_AUTH_INVALID
;
2504 #ifdef CONFIG_VNC_TLS
2506 vs
->auth
= VNC_AUTH_VENCRYPT
;
2508 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2509 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
2511 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2512 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
2516 VNC_DEBUG("Initializing VNC server with no auth\n");
2517 vs
->auth
= VNC_AUTH_NONE
;
2518 #ifdef CONFIG_VNC_TLS
2519 vs
->subauth
= VNC_AUTH_INVALID
;
2525 /* connect to viewer */
2526 if (strncmp(display
, "unix:", 5) == 0)
2527 vs
->lsock
= unix_connect(display
+5);
2529 vs
->lsock
= inet_connect(display
, SOCK_STREAM
);
2530 if (-1 == vs
->lsock
) {
2535 vs
->csock
= vs
->lsock
;
2542 /* listen for connects */
2544 dpy
= qemu_malloc(256);
2545 if (strncmp(display
, "unix:", 5) == 0) {
2546 strcpy(dpy
, "unix:");
2547 vs
->lsock
= unix_listen(display
+5, dpy
+5, 256-5);
2549 vs
->lsock
= inet_listen(display
, dpy
, 256, SOCK_STREAM
, 5900);
2551 if (-1 == vs
->lsock
) {
2560 return qemu_set_fd_handler2(vs
->lsock
, vnc_listen_poll
, vnc_listen_read
, NULL
, vs
);