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"
34 #define VNC_REFRESH_INTERVAL (1000 / 30)
37 #include "vnc_keysym.h"
42 #include <gnutls/gnutls.h>
43 #include <gnutls/x509.h>
44 #endif /* CONFIG_VNC_TLS */
46 // #define _VNC_DEBUG 1
49 #define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
51 #if defined(CONFIG_VNC_TLS) && _VNC_DEBUG >= 2
52 /* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
53 static void vnc_debug_gnutls_log(int level
, const char* str
) {
54 VNC_DEBUG("%d %s", level
, str
);
56 #endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
58 #define VNC_DEBUG(fmt, ...) do { } while (0)
61 #define count_bits(c, v) { \
62 for (c = 0; v; v >>= 1) \
75 typedef struct VncState VncState
;
77 typedef int VncReadEvent(VncState
*vs
, uint8_t *data
, size_t len
);
79 typedef void VncWritePixels(VncState
*vs
, void *data
, int size
);
81 typedef void VncSendHextileTile(VncState
*vs
,
82 int x
, int y
, int w
, int h
,
85 int *has_bg
, int *has_fg
);
87 #define VNC_MAX_WIDTH 2048
88 #define VNC_MAX_HEIGHT 2048
89 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
91 #define VNC_AUTH_CHALLENGE_SIZE 16
93 typedef struct VncDisplay VncDisplay
;
100 kbd_layout_t
*kbd_layout
;
105 #ifdef CONFIG_VNC_TLS
123 uint32_t dirty_row
[VNC_MAX_HEIGHT
][VNC_DIRTY_WORDS
];
130 uint32_t vnc_encoding
;
131 uint8_t tight_quality
;
132 uint8_t tight_compression
;
137 char challenge
[VNC_AUTH_CHALLENGE_SIZE
];
139 #ifdef CONFIG_VNC_TLS
141 gnutls_session_t tls_session
;
146 /* current output mode information */
147 VncWritePixels
*write_pixels
;
148 VncSendHextileTile
*send_hextile_tile
;
149 DisplaySurface clientds
, serverds
;
151 CaptureVoiceOut
*audio_cap
;
152 struct audsettings as
;
154 VncReadEvent
*read_handler
;
155 size_t read_handler_expect
;
157 uint8_t modifiers_state
[256];
161 z_stream zlib_stream
[4];
166 static VncDisplay
*vnc_display
; /* needed for info vnc */
167 static DisplayChangeListener
*dcl
;
169 void do_info_vnc(void)
171 if (vnc_display
== NULL
|| vnc_display
->display
== NULL
)
172 term_printf("VNC server disabled\n");
174 term_printf("VNC server active on: ");
175 term_print_filename(vnc_display
->display
);
178 if (vnc_display
->clients
== NULL
)
179 term_printf("No client connected\n");
181 term_printf("Client connected\n");
185 static inline uint32_t vnc_has_feature(VncState
*vs
, int feature
) {
186 return (vs
->features
& (1 << feature
));
190 1) Get the queue working for IO.
191 2) there is some weirdness when using the -S option (the screen is grey
192 and not totally invalidated
193 3) resolutions > 1024
196 static void vnc_write(VncState
*vs
, const void *data
, size_t len
);
197 static void vnc_write_u32(VncState
*vs
, uint32_t value
);
198 static void vnc_write_s32(VncState
*vs
, int32_t value
);
199 static void vnc_write_u16(VncState
*vs
, uint16_t value
);
200 static void vnc_write_u8(VncState
*vs
, uint8_t value
);
201 static void vnc_flush(VncState
*vs
);
202 static void vnc_update_client(void *opaque
);
203 static void vnc_client_read(void *opaque
);
205 static void vnc_colordepth(VncState
*vs
);
207 static inline void vnc_set_bit(uint32_t *d
, int k
)
209 d
[k
>> 5] |= 1 << (k
& 0x1f);
212 static inline void vnc_clear_bit(uint32_t *d
, int k
)
214 d
[k
>> 5] &= ~(1 << (k
& 0x1f));
217 static inline void vnc_set_bits(uint32_t *d
, int n
, int nb_words
)
227 d
[j
++] = (1 << n
) - 1;
232 static inline int vnc_get_bit(const uint32_t *d
, int k
)
234 return (d
[k
>> 5] >> (k
& 0x1f)) & 1;
237 static inline int vnc_and_bits(const uint32_t *d1
, const uint32_t *d2
,
241 for(i
= 0; i
< nb_words
; i
++) {
242 if ((d1
[i
] & d2
[i
]) != 0)
248 static void vnc_update(VncState
*vs
, int x
, int y
, int w
, int h
)
254 /* round x down to ensure the loop only spans one 16-pixel block per,
255 iteration. otherwise, if (x % 16) != 0, the last iteration may span
256 two 16-pixel blocks but we only mark the first as dirty
261 x
= MIN(x
, vs
->serverds
.width
);
262 y
= MIN(y
, vs
->serverds
.height
);
263 w
= MIN(x
+ w
, vs
->serverds
.width
) - x
;
264 h
= MIN(h
, vs
->serverds
.height
);
267 for (i
= 0; i
< w
; i
+= 16)
268 vnc_set_bit(vs
->dirty_row
[y
], (x
+ i
) / 16);
271 static void vnc_dpy_update(DisplayState
*ds
, int x
, int y
, int w
, int h
)
273 VncDisplay
*vd
= ds
->opaque
;
274 VncState
*vs
= vd
->clients
;
276 vnc_update(vs
, x
, y
, w
, h
);
281 static void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
284 vnc_write_u16(vs
, x
);
285 vnc_write_u16(vs
, y
);
286 vnc_write_u16(vs
, w
);
287 vnc_write_u16(vs
, h
);
289 vnc_write_s32(vs
, encoding
);
292 static void buffer_reserve(Buffer
*buffer
, size_t len
)
294 if ((buffer
->capacity
- buffer
->offset
) < len
) {
295 buffer
->capacity
+= (len
+ 1024);
296 buffer
->buffer
= qemu_realloc(buffer
->buffer
, buffer
->capacity
);
297 if (buffer
->buffer
== NULL
) {
298 fprintf(stderr
, "vnc: out of memory\n");
304 static int buffer_empty(Buffer
*buffer
)
306 return buffer
->offset
== 0;
309 static uint8_t *buffer_end(Buffer
*buffer
)
311 return buffer
->buffer
+ buffer
->offset
;
314 static void buffer_reset(Buffer
*buffer
)
319 static void buffer_append(Buffer
*buffer
, const void *data
, size_t len
)
321 memcpy(buffer
->buffer
+ buffer
->offset
, data
, len
);
322 buffer
->offset
+= len
;
325 static void vnc_resize(VncState
*vs
)
327 DisplayState
*ds
= vs
->ds
;
331 vs
->old_data
= qemu_realloc(vs
->old_data
, ds_get_linesize(ds
) * ds_get_height(ds
));
333 if (vs
->old_data
== NULL
) {
334 fprintf(stderr
, "vnc: memory allocation failed\n");
338 if (ds_get_bytes_per_pixel(ds
) != vs
->serverds
.pf
.bytes_per_pixel
)
339 console_color_init(ds
);
341 size_changed
= ds_get_width(ds
) != vs
->serverds
.width
||
342 ds_get_height(ds
) != vs
->serverds
.height
;
343 vs
->serverds
= *(ds
->surface
);
345 if (vs
->csock
!= -1 && vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
346 vnc_write_u8(vs
, 0); /* msg id */
348 vnc_write_u16(vs
, 1); /* number of rects */
349 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(ds
), ds_get_height(ds
),
350 VNC_ENCODING_DESKTOPRESIZE
);
355 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
356 memset(vs
->old_data
, 42, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
359 static void vnc_dpy_resize(DisplayState
*ds
)
361 VncDisplay
*vd
= ds
->opaque
;
362 VncState
*vs
= vd
->clients
;
370 static void vnc_write_pixels_copy(VncState
*vs
, void *pixels
, int size
)
372 vnc_write(vs
, pixels
, size
);
375 /* slowest but generic code. */
376 static void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
380 r
= ((((v
& vs
->serverds
.pf
.rmask
) >> vs
->serverds
.pf
.rshift
) << vs
->clientds
.pf
.rbits
) >>
381 vs
->serverds
.pf
.rbits
);
382 g
= ((((v
& vs
->serverds
.pf
.gmask
) >> vs
->serverds
.pf
.gshift
) << vs
->clientds
.pf
.gbits
) >>
383 vs
->serverds
.pf
.gbits
);
384 b
= ((((v
& vs
->serverds
.pf
.bmask
) >> vs
->serverds
.pf
.bshift
) << vs
->clientds
.pf
.bbits
) >>
385 vs
->serverds
.pf
.bbits
);
386 v
= (r
<< vs
->clientds
.pf
.rshift
) |
387 (g
<< vs
->clientds
.pf
.gshift
) |
388 (b
<< vs
->clientds
.pf
.bshift
);
389 switch(vs
->clientds
.pf
.bytes_per_pixel
) {
394 if (vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) {
404 if (vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) {
419 static void vnc_write_pixels_generic(VncState
*vs
, void *pixels1
, int size
)
423 if (vs
->serverds
.pf
.bytes_per_pixel
== 4) {
424 uint32_t *pixels
= pixels1
;
427 for(i
= 0; i
< n
; i
++) {
428 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
429 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
431 } else if (vs
->serverds
.pf
.bytes_per_pixel
== 2) {
432 uint16_t *pixels
= pixels1
;
435 for(i
= 0; i
< n
; i
++) {
436 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
437 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
439 } else if (vs
->serverds
.pf
.bytes_per_pixel
== 1) {
440 uint8_t *pixels
= pixels1
;
443 for(i
= 0; i
< n
; i
++) {
444 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
445 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
448 fprintf(stderr
, "vnc_write_pixels_generic: VncState color depth not supported\n");
452 static void send_framebuffer_update_raw(VncState
*vs
, int x
, int y
, int w
, int h
)
457 row
= ds_get_data(vs
->ds
) + y
* ds_get_linesize(vs
->ds
) + x
* ds_get_bytes_per_pixel(vs
->ds
);
458 for (i
= 0; i
< h
; i
++) {
459 vs
->write_pixels(vs
, row
, w
* ds_get_bytes_per_pixel(vs
->ds
));
460 row
+= ds_get_linesize(vs
->ds
);
464 static void hextile_enc_cord(uint8_t *ptr
, int x
, int y
, int w
, int h
)
466 ptr
[0] = ((x
& 0x0F) << 4) | (y
& 0x0F);
467 ptr
[1] = (((w
- 1) & 0x0F) << 4) | ((h
- 1) & 0x0F);
471 #include "vnchextile.h"
475 #include "vnchextile.h"
479 #include "vnchextile.h"
484 #include "vnchextile.h"
490 #include "vnchextile.h"
496 #include "vnchextile.h"
500 static void send_framebuffer_update_hextile(VncState
*vs
, int x
, int y
, int w
, int h
)
504 uint8_t *last_fg
, *last_bg
;
506 last_fg
= (uint8_t *) qemu_malloc(vs
->serverds
.pf
.bytes_per_pixel
);
507 last_bg
= (uint8_t *) qemu_malloc(vs
->serverds
.pf
.bytes_per_pixel
);
509 for (j
= y
; j
< (y
+ h
); j
+= 16) {
510 for (i
= x
; i
< (x
+ w
); i
+= 16) {
511 vs
->send_hextile_tile(vs
, i
, j
,
512 MIN(16, x
+ w
- i
), MIN(16, y
+ h
- j
),
513 last_bg
, last_fg
, &has_bg
, &has_fg
);
521 static void vnc_zlib_init(VncState
*vs
)
524 for (i
=0; i
<(sizeof(vs
->zlib_stream
) / sizeof(z_stream
)); i
++)
525 vs
->zlib_stream
[i
].opaque
= NULL
;
528 static void vnc_zlib_start(VncState
*vs
)
530 buffer_reset(&vs
->zlib
);
532 // make the output buffer be the zlib buffer, so we can compress it later
533 vs
->zlib_tmp
= vs
->output
;
534 vs
->output
= vs
->zlib
;
537 static int vnc_zlib_stop(VncState
*vs
, int stream_id
)
539 z_streamp zstream
= &vs
->zlib_stream
[stream_id
];
542 // switch back to normal output/zlib buffers
543 vs
->zlib
= vs
->output
;
544 vs
->output
= vs
->zlib_tmp
;
546 // compress the zlib buffer
548 // initialize the stream
549 // XXX need one stream per session
550 if (zstream
->opaque
!= vs
) {
553 VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id
);
554 VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream
->opaque
, vs
);
555 zstream
->zalloc
= Z_NULL
;
556 zstream
->zfree
= Z_NULL
;
558 err
= deflateInit2(zstream
, vs
->tight_compression
, Z_DEFLATED
, MAX_WBITS
,
559 MAX_MEM_LEVEL
, Z_DEFAULT_STRATEGY
);
562 fprintf(stderr
, "VNC: error initializing zlib\n");
566 zstream
->opaque
= vs
;
569 // XXX what to do if tight_compression changed in between?
571 // reserve memory in output buffer
572 buffer_reserve(&vs
->output
, vs
->zlib
.offset
+ 64);
575 zstream
->next_in
= vs
->zlib
.buffer
;
576 zstream
->avail_in
= vs
->zlib
.offset
;
577 zstream
->next_out
= vs
->output
.buffer
+ vs
->output
.offset
;
578 zstream
->avail_out
= vs
->output
.capacity
- vs
->output
.offset
;
579 zstream
->data_type
= Z_BINARY
;
580 previous_out
= zstream
->total_out
;
583 if (deflate(zstream
, Z_SYNC_FLUSH
) != Z_OK
) {
584 fprintf(stderr
, "VNC: error during zlib compression\n");
588 vs
->output
.offset
= vs
->output
.capacity
- zstream
->avail_out
;
589 return zstream
->total_out
- previous_out
;
592 static void send_framebuffer_update_zlib(VncState
*vs
, int x
, int y
, int w
, int h
)
594 int old_offset
, new_offset
, bytes_written
;
596 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_ZLIB
);
598 // remember where we put in the follow-up size
599 old_offset
= vs
->output
.offset
;
600 vnc_write_s32(vs
, 0);
602 // compress the stream
604 send_framebuffer_update_raw(vs
, x
, y
, w
, h
);
605 bytes_written
= vnc_zlib_stop(vs
, 0);
607 if (bytes_written
== -1)
611 new_offset
= vs
->output
.offset
;
612 vs
->output
.offset
= old_offset
;
613 vnc_write_u32(vs
, bytes_written
);
614 vs
->output
.offset
= new_offset
;
617 static void send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
619 switch(vs
->vnc_encoding
) {
620 case VNC_ENCODING_ZLIB
:
621 send_framebuffer_update_zlib(vs
, x
, y
, w
, h
);
623 case VNC_ENCODING_HEXTILE
:
624 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
625 send_framebuffer_update_hextile(vs
, x
, y
, w
, h
);
628 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
629 send_framebuffer_update_raw(vs
, x
, y
, w
, h
);
634 static void vnc_copy(VncState
*vs
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
636 vnc_update_client(vs
);
638 vnc_write_u8(vs
, 0); /* msg id */
640 vnc_write_u16(vs
, 1); /* number of rects */
641 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
642 vnc_write_u16(vs
, src_x
);
643 vnc_write_u16(vs
, src_y
);
647 static void vnc_dpy_copy(DisplayState
*ds
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
649 VncDisplay
*vd
= ds
->opaque
;
650 VncState
*vs
= vd
->clients
;
652 if (vnc_has_feature(vs
, VNC_FEATURE_COPYRECT
))
653 vnc_copy(vs
, src_x
, src_y
, dst_x
, dst_y
, w
, h
);
655 vnc_update(vs
, dst_x
, dst_y
, w
, h
);
660 static int find_dirty_height(VncState
*vs
, int y
, int last_x
, int x
)
664 for (h
= 1; h
< (vs
->serverds
.height
- y
); h
++) {
666 if (!vnc_get_bit(vs
->dirty_row
[y
+ h
], last_x
))
668 for (tmp_x
= last_x
; tmp_x
< x
; tmp_x
++)
669 vnc_clear_bit(vs
->dirty_row
[y
+ h
], tmp_x
);
675 static void vnc_update_client(void *opaque
)
677 VncState
*vs
= opaque
;
678 if (vs
->need_update
&& vs
->csock
!= -1) {
682 uint32_t width_mask
[VNC_DIRTY_WORDS
];
689 vnc_set_bits(width_mask
, (ds_get_width(vs
->ds
) / 16), VNC_DIRTY_WORDS
);
691 /* Walk through the dirty map and eliminate tiles that
692 really aren't dirty */
693 row
= ds_get_data(vs
->ds
);
694 old_row
= vs
->old_data
;
696 for (y
= 0; y
< ds_get_height(vs
->ds
); y
++) {
697 if (vnc_and_bits(vs
->dirty_row
[y
], width_mask
, VNC_DIRTY_WORDS
)) {
703 old_ptr
= (char*)old_row
;
705 for (x
= 0; x
< ds_get_width(vs
->ds
); x
+= 16) {
706 if (memcmp(old_ptr
, ptr
, 16 * ds_get_bytes_per_pixel(vs
->ds
)) == 0) {
707 vnc_clear_bit(vs
->dirty_row
[y
], (x
/ 16));
710 memcpy(old_ptr
, ptr
, 16 * ds_get_bytes_per_pixel(vs
->ds
));
713 ptr
+= 16 * ds_get_bytes_per_pixel(vs
->ds
);
714 old_ptr
+= 16 * ds_get_bytes_per_pixel(vs
->ds
);
718 row
+= ds_get_linesize(vs
->ds
);
719 old_row
+= ds_get_linesize(vs
->ds
);
722 if (!has_dirty
&& !vs
->audio_cap
) {
723 qemu_mod_timer(vs
->timer
, qemu_get_clock(rt_clock
) + VNC_REFRESH_INTERVAL
);
727 /* Count rectangles */
729 vnc_write_u8(vs
, 0); /* msg id */
731 saved_offset
= vs
->output
.offset
;
732 vnc_write_u16(vs
, 0);
734 for (y
= 0; y
< vs
->serverds
.height
; y
++) {
737 for (x
= 0; x
< vs
->serverds
.width
/ 16; x
++) {
738 if (vnc_get_bit(vs
->dirty_row
[y
], x
)) {
742 vnc_clear_bit(vs
->dirty_row
[y
], x
);
745 int h
= find_dirty_height(vs
, y
, last_x
, x
);
746 send_framebuffer_update(vs
, last_x
* 16, y
, (x
- last_x
) * 16, h
);
753 int h
= find_dirty_height(vs
, y
, last_x
, x
);
754 send_framebuffer_update(vs
, last_x
* 16, y
, (x
- last_x
) * 16, h
);
758 vs
->output
.buffer
[saved_offset
] = (n_rectangles
>> 8) & 0xFF;
759 vs
->output
.buffer
[saved_offset
+ 1] = n_rectangles
& 0xFF;
764 if (vs
->csock
!= -1) {
765 qemu_mod_timer(vs
->timer
, qemu_get_clock(rt_clock
) + VNC_REFRESH_INTERVAL
);
771 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
773 VncState
*vs
= opaque
;
776 case AUD_CNOTIFY_DISABLE
:
777 vnc_write_u8(vs
, 255);
779 vnc_write_u16(vs
, 0);
783 case AUD_CNOTIFY_ENABLE
:
784 vnc_write_u8(vs
, 255);
786 vnc_write_u16(vs
, 1);
792 static void audio_capture_destroy(void *opaque
)
796 static void audio_capture(void *opaque
, void *buf
, int size
)
798 VncState
*vs
= opaque
;
800 vnc_write_u8(vs
, 255);
802 vnc_write_u16(vs
, 2);
803 vnc_write_u32(vs
, size
);
804 vnc_write(vs
, buf
, size
);
808 static void audio_add(VncState
*vs
)
810 struct audio_capture_ops ops
;
813 term_printf ("audio already running\n");
817 ops
.notify
= audio_capture_notify
;
818 ops
.destroy
= audio_capture_destroy
;
819 ops
.capture
= audio_capture
;
821 vs
->audio_cap
= AUD_add_capture(NULL
, &vs
->as
, &ops
, vs
);
822 if (!vs
->audio_cap
) {
823 term_printf ("Failed to add audio capture\n");
827 static void audio_del(VncState
*vs
)
830 AUD_del_capture(vs
->audio_cap
, vs
);
831 vs
->audio_cap
= NULL
;
835 static int vnc_client_io_error(VncState
*vs
, int ret
, int last_errno
)
837 if (ret
== 0 || ret
== -1) {
839 switch (last_errno
) {
851 VNC_DEBUG("Closing down client sock %d %d\n", ret
, ret
< 0 ? last_errno
: 0);
852 qemu_set_fd_handler2(vs
->csock
, NULL
, NULL
, NULL
, NULL
);
853 closesocket(vs
->csock
);
854 qemu_del_timer(vs
->timer
);
855 qemu_free_timer(vs
->timer
);
856 if (vs
->input
.buffer
) qemu_free(vs
->input
.buffer
);
857 if (vs
->output
.buffer
) qemu_free(vs
->output
.buffer
);
858 #ifdef CONFIG_VNC_TLS
859 if (vs
->tls_session
) {
860 gnutls_deinit(vs
->tls_session
);
861 vs
->tls_session
= NULL
;
863 #endif /* CONFIG_VNC_TLS */
866 VncState
*p
, *parent
= NULL
;
867 for (p
= vs
->vd
->clients
; p
!= NULL
; p
= p
->next
) {
870 parent
->next
= p
->next
;
872 vs
->vd
->clients
= p
->next
;
877 if (!vs
->vd
->clients
)
880 qemu_free(vs
->old_data
);
888 static void vnc_client_error(VncState
*vs
)
890 vnc_client_io_error(vs
, -1, EINVAL
);
893 static void vnc_client_write(void *opaque
)
896 VncState
*vs
= opaque
;
898 #ifdef CONFIG_VNC_TLS
899 if (vs
->tls_session
) {
900 ret
= gnutls_write(vs
->tls_session
, vs
->output
.buffer
, vs
->output
.offset
);
902 if (ret
== GNUTLS_E_AGAIN
)
909 #endif /* CONFIG_VNC_TLS */
910 ret
= send(vs
->csock
, vs
->output
.buffer
, vs
->output
.offset
, 0);
911 ret
= vnc_client_io_error(vs
, ret
, socket_error());
915 memmove(vs
->output
.buffer
, vs
->output
.buffer
+ ret
, (vs
->output
.offset
- ret
));
916 vs
->output
.offset
-= ret
;
918 if (vs
->output
.offset
== 0) {
919 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
923 static void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
925 vs
->read_handler
= func
;
926 vs
->read_handler_expect
= expecting
;
929 static void vnc_client_read(void *opaque
)
931 VncState
*vs
= opaque
;
934 buffer_reserve(&vs
->input
, 4096);
936 #ifdef CONFIG_VNC_TLS
937 if (vs
->tls_session
) {
938 ret
= gnutls_read(vs
->tls_session
, buffer_end(&vs
->input
), 4096);
940 if (ret
== GNUTLS_E_AGAIN
)
947 #endif /* CONFIG_VNC_TLS */
948 ret
= recv(vs
->csock
, buffer_end(&vs
->input
), 4096, 0);
949 ret
= vnc_client_io_error(vs
, ret
, socket_error());
953 vs
->input
.offset
+= ret
;
955 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
956 size_t len
= vs
->read_handler_expect
;
959 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
964 memmove(vs
->input
.buffer
, vs
->input
.buffer
+ len
, (vs
->input
.offset
- len
));
965 vs
->input
.offset
-= len
;
967 vs
->read_handler_expect
= ret
;
972 static void vnc_write(VncState
*vs
, const void *data
, size_t len
)
974 buffer_reserve(&vs
->output
, len
);
976 if (buffer_empty(&vs
->output
)) {
977 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
980 buffer_append(&vs
->output
, data
, len
);
983 static void vnc_write_s32(VncState
*vs
, int32_t value
)
985 vnc_write_u32(vs
, *(uint32_t *)&value
);
988 static void vnc_write_u32(VncState
*vs
, uint32_t value
)
992 buf
[0] = (value
>> 24) & 0xFF;
993 buf
[1] = (value
>> 16) & 0xFF;
994 buf
[2] = (value
>> 8) & 0xFF;
995 buf
[3] = value
& 0xFF;
997 vnc_write(vs
, buf
, 4);
1000 static void vnc_write_u16(VncState
*vs
, uint16_t value
)
1004 buf
[0] = (value
>> 8) & 0xFF;
1005 buf
[1] = value
& 0xFF;
1007 vnc_write(vs
, buf
, 2);
1010 static void vnc_write_u8(VncState
*vs
, uint8_t value
)
1012 vnc_write(vs
, (char *)&value
, 1);
1015 static void vnc_flush(VncState
*vs
)
1017 if (vs
->output
.offset
)
1018 vnc_client_write(vs
);
1021 static uint8_t read_u8(uint8_t *data
, size_t offset
)
1023 return data
[offset
];
1026 static uint16_t read_u16(uint8_t *data
, size_t offset
)
1028 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
1031 static int32_t read_s32(uint8_t *data
, size_t offset
)
1033 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1034 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1037 static uint32_t read_u32(uint8_t *data
, size_t offset
)
1039 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
1040 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
1043 #ifdef CONFIG_VNC_TLS
1044 static ssize_t
vnc_tls_push(gnutls_transport_ptr_t transport
,
1047 struct VncState
*vs
= (struct VncState
*)transport
;
1051 ret
= send(vs
->csock
, data
, len
, 0);
1061 static ssize_t
vnc_tls_pull(gnutls_transport_ptr_t transport
,
1064 struct VncState
*vs
= (struct VncState
*)transport
;
1068 ret
= recv(vs
->csock
, data
, len
, 0);
1076 #endif /* CONFIG_VNC_TLS */
1078 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1082 static void check_pointer_type_change(VncState
*vs
, int absolute
)
1084 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1085 vnc_write_u8(vs
, 0);
1086 vnc_write_u8(vs
, 0);
1087 vnc_write_u16(vs
, 1);
1088 vnc_framebuffer_update(vs
, absolute
, 0,
1089 ds_get_width(vs
->ds
), ds_get_height(vs
->ds
),
1090 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1093 vs
->absolute
= absolute
;
1096 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1101 if (button_mask
& 0x01)
1102 buttons
|= MOUSE_EVENT_LBUTTON
;
1103 if (button_mask
& 0x02)
1104 buttons
|= MOUSE_EVENT_MBUTTON
;
1105 if (button_mask
& 0x04)
1106 buttons
|= MOUSE_EVENT_RBUTTON
;
1107 if (button_mask
& 0x08)
1109 if (button_mask
& 0x10)
1113 kbd_mouse_event(x
* 0x7FFF / (ds_get_width(vs
->ds
) - 1),
1114 y
* 0x7FFF / (ds_get_height(vs
->ds
) - 1),
1116 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1120 kbd_mouse_event(x
, y
, dz
, buttons
);
1122 if (vs
->last_x
!= -1)
1123 kbd_mouse_event(x
- vs
->last_x
,
1130 check_pointer_type_change(vs
, kbd_mouse_is_absolute());
1133 static void reset_keys(VncState
*vs
)
1136 for(i
= 0; i
< 256; i
++) {
1137 if (vs
->modifiers_state
[i
]) {
1139 kbd_put_keycode(0xe0);
1140 kbd_put_keycode(i
| 0x80);
1141 vs
->modifiers_state
[i
] = 0;
1146 static void press_key(VncState
*vs
, int keysym
)
1148 kbd_put_keycode(keysym2scancode(vs
->vd
->kbd_layout
, keysym
) & 0x7f);
1149 kbd_put_keycode(keysym2scancode(vs
->vd
->kbd_layout
, keysym
) | 0x80);
1152 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1154 /* QEMU console switch */
1156 case 0x2a: /* Left Shift */
1157 case 0x36: /* Right Shift */
1158 case 0x1d: /* Left CTRL */
1159 case 0x9d: /* Right CTRL */
1160 case 0x38: /* Left ALT */
1161 case 0xb8: /* Right ALT */
1163 vs
->modifiers_state
[keycode
] = 1;
1165 vs
->modifiers_state
[keycode
] = 0;
1167 case 0x02 ... 0x0a: /* '1' to '9' keys */
1168 if (down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1169 /* Reset the modifiers sent to the current console */
1171 console_select(keycode
- 0x02);
1175 case 0x3a: /* CapsLock */
1176 case 0x45: /* NumLock */
1178 vs
->modifiers_state
[keycode
] ^= 1;
1182 if (keycode_is_keypad(vs
->vd
->kbd_layout
, keycode
)) {
1183 /* If the numlock state needs to change then simulate an additional
1184 keypress before sending this one. This will happen if the user
1185 toggles numlock away from the VNC window.
1187 if (keysym_is_numlock(vs
->vd
->kbd_layout
, sym
& 0xFFFF)) {
1188 if (!vs
->modifiers_state
[0x45]) {
1189 vs
->modifiers_state
[0x45] = 1;
1190 press_key(vs
, 0xff7f);
1193 if (vs
->modifiers_state
[0x45]) {
1194 vs
->modifiers_state
[0x45] = 0;
1195 press_key(vs
, 0xff7f);
1200 if (is_graphic_console()) {
1202 kbd_put_keycode(0xe0);
1204 kbd_put_keycode(keycode
& 0x7f);
1206 kbd_put_keycode(keycode
| 0x80);
1208 /* QEMU console emulation */
1211 case 0x2a: /* Left Shift */
1212 case 0x36: /* Right Shift */
1213 case 0x1d: /* Left CTRL */
1214 case 0x9d: /* Right CTRL */
1215 case 0x38: /* Left ALT */
1216 case 0xb8: /* Right ALT */
1220 kbd_put_keysym(QEMU_KEY_UP
);
1224 kbd_put_keysym(QEMU_KEY_DOWN
);
1228 kbd_put_keysym(QEMU_KEY_LEFT
);
1232 kbd_put_keysym(QEMU_KEY_RIGHT
);
1236 kbd_put_keysym(QEMU_KEY_DELETE
);
1240 kbd_put_keysym(QEMU_KEY_HOME
);
1244 kbd_put_keysym(QEMU_KEY_END
);
1248 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1252 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1255 kbd_put_keysym(sym
);
1262 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1266 if (sym
>= 'A' && sym
<= 'Z' && is_graphic_console())
1267 sym
= sym
- 'A' + 'a';
1269 keycode
= keysym2scancode(vs
->vd
->kbd_layout
, sym
& 0xFFFF);
1270 do_key_event(vs
, down
, keycode
, sym
);
1273 static void ext_key_event(VncState
*vs
, int down
,
1274 uint32_t sym
, uint16_t keycode
)
1276 /* if the user specifies a keyboard layout, always use it */
1277 if (keyboard_layout
)
1278 key_event(vs
, down
, sym
);
1280 do_key_event(vs
, down
, keycode
, sym
);
1283 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1284 int x_position
, int y_position
,
1287 if (x_position
> ds_get_width(vs
->ds
))
1288 x_position
= ds_get_width(vs
->ds
);
1289 if (y_position
> ds_get_height(vs
->ds
))
1290 y_position
= ds_get_height(vs
->ds
);
1291 if (x_position
+ w
>= ds_get_width(vs
->ds
))
1292 w
= ds_get_width(vs
->ds
) - x_position
;
1293 if (y_position
+ h
>= ds_get_height(vs
->ds
))
1294 h
= ds_get_height(vs
->ds
) - y_position
;
1297 vs
->need_update
= 1;
1299 char *old_row
= vs
->old_data
+ y_position
* ds_get_linesize(vs
->ds
);
1301 for (i
= 0; i
< h
; i
++) {
1302 vnc_set_bits(vs
->dirty_row
[y_position
+ i
],
1303 (ds_get_width(vs
->ds
) / 16), VNC_DIRTY_WORDS
);
1304 memset(old_row
, 42, ds_get_width(vs
->ds
) * ds_get_bytes_per_pixel(vs
->ds
));
1305 old_row
+= ds_get_linesize(vs
->ds
);
1310 static void send_ext_key_event_ack(VncState
*vs
)
1312 vnc_write_u8(vs
, 0);
1313 vnc_write_u8(vs
, 0);
1314 vnc_write_u16(vs
, 1);
1315 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
), ds_get_height(vs
->ds
),
1316 VNC_ENCODING_EXT_KEY_EVENT
);
1320 static void send_ext_audio_ack(VncState
*vs
)
1322 vnc_write_u8(vs
, 0);
1323 vnc_write_u8(vs
, 0);
1324 vnc_write_u16(vs
, 1);
1325 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
), ds_get_height(vs
->ds
),
1326 VNC_ENCODING_AUDIO
);
1330 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1333 unsigned int enc
= 0;
1337 vs
->vnc_encoding
= 0;
1338 vs
->tight_compression
= 9;
1339 vs
->tight_quality
= 9;
1342 for (i
= n_encodings
- 1; i
>= 0; i
--) {
1345 case VNC_ENCODING_RAW
:
1346 vs
->vnc_encoding
= enc
;
1348 case VNC_ENCODING_COPYRECT
:
1349 vs
->features
|= VNC_FEATURE_COPYRECT_MASK
;
1351 case VNC_ENCODING_HEXTILE
:
1352 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
1353 vs
->vnc_encoding
= enc
;
1355 case VNC_ENCODING_ZLIB
:
1356 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
1357 vs
->vnc_encoding
= enc
;
1359 case VNC_ENCODING_DESKTOPRESIZE
:
1360 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
1362 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
1363 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
1365 case VNC_ENCODING_EXT_KEY_EVENT
:
1366 send_ext_key_event_ack(vs
);
1368 case VNC_ENCODING_AUDIO
:
1369 send_ext_audio_ack(vs
);
1371 case VNC_ENCODING_WMVi
:
1372 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
1374 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
1375 vs
->tight_compression
= (enc
& 0x0F);
1377 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
1378 vs
->tight_quality
= (enc
& 0x0F);
1381 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
1386 check_pointer_type_change(vs
, kbd_mouse_is_absolute());
1389 static void set_pixel_conversion(VncState
*vs
)
1391 if ((vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) ==
1392 (vs
->ds
->surface
->flags
& QEMU_BIG_ENDIAN_FLAG
) &&
1393 !memcmp(&(vs
->clientds
.pf
), &(vs
->ds
->surface
->pf
), sizeof(PixelFormat
))) {
1394 vs
->write_pixels
= vnc_write_pixels_copy
;
1395 switch (vs
->ds
->surface
->pf
.bits_per_pixel
) {
1397 vs
->send_hextile_tile
= send_hextile_tile_8
;
1400 vs
->send_hextile_tile
= send_hextile_tile_16
;
1403 vs
->send_hextile_tile
= send_hextile_tile_32
;
1407 vs
->write_pixels
= vnc_write_pixels_generic
;
1408 switch (vs
->ds
->surface
->pf
.bits_per_pixel
) {
1410 vs
->send_hextile_tile
= send_hextile_tile_generic_8
;
1413 vs
->send_hextile_tile
= send_hextile_tile_generic_16
;
1416 vs
->send_hextile_tile
= send_hextile_tile_generic_32
;
1422 static void set_pixel_format(VncState
*vs
,
1423 int bits_per_pixel
, int depth
,
1424 int big_endian_flag
, int true_color_flag
,
1425 int red_max
, int green_max
, int blue_max
,
1426 int red_shift
, int green_shift
, int blue_shift
)
1428 if (!true_color_flag
) {
1429 vnc_client_error(vs
);
1433 vs
->clientds
= vs
->serverds
;
1434 vs
->clientds
.pf
.rmax
= red_max
;
1435 count_bits(vs
->clientds
.pf
.rbits
, red_max
);
1436 vs
->clientds
.pf
.rshift
= red_shift
;
1437 vs
->clientds
.pf
.rmask
= red_max
<< red_shift
;
1438 vs
->clientds
.pf
.gmax
= green_max
;
1439 count_bits(vs
->clientds
.pf
.gbits
, green_max
);
1440 vs
->clientds
.pf
.gshift
= green_shift
;
1441 vs
->clientds
.pf
.gmask
= green_max
<< green_shift
;
1442 vs
->clientds
.pf
.bmax
= blue_max
;
1443 count_bits(vs
->clientds
.pf
.bbits
, blue_max
);
1444 vs
->clientds
.pf
.bshift
= blue_shift
;
1445 vs
->clientds
.pf
.bmask
= blue_max
<< blue_shift
;
1446 vs
->clientds
.pf
.bits_per_pixel
= bits_per_pixel
;
1447 vs
->clientds
.pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
1448 vs
->clientds
.pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
1449 vs
->clientds
.flags
= big_endian_flag
? QEMU_BIG_ENDIAN_FLAG
: 0x00;
1451 set_pixel_conversion(vs
);
1453 vga_hw_invalidate();
1457 static void pixel_format_message (VncState
*vs
) {
1458 char pad
[3] = { 0, 0, 0 };
1460 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.bits_per_pixel
); /* bits-per-pixel */
1461 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.depth
); /* depth */
1463 #ifdef WORDS_BIGENDIAN
1464 vnc_write_u8(vs
, 1); /* big-endian-flag */
1466 vnc_write_u8(vs
, 0); /* big-endian-flag */
1468 vnc_write_u8(vs
, 1); /* true-color-flag */
1469 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.rmax
); /* red-max */
1470 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.gmax
); /* green-max */
1471 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.bmax
); /* blue-max */
1472 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.rshift
); /* red-shift */
1473 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.gshift
); /* green-shift */
1474 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.bshift
); /* blue-shift */
1475 if (vs
->ds
->surface
->pf
.bits_per_pixel
== 32)
1476 vs
->send_hextile_tile
= send_hextile_tile_32
;
1477 else if (vs
->ds
->surface
->pf
.bits_per_pixel
== 16)
1478 vs
->send_hextile_tile
= send_hextile_tile_16
;
1479 else if (vs
->ds
->surface
->pf
.bits_per_pixel
== 8)
1480 vs
->send_hextile_tile
= send_hextile_tile_8
;
1481 vs
->clientds
= *(vs
->ds
->surface
);
1482 vs
->clientds
.flags
|= ~QEMU_ALLOCATED_FLAG
;
1483 vs
->write_pixels
= vnc_write_pixels_copy
;
1485 vnc_write(vs
, pad
, 3); /* padding */
1488 static void vnc_dpy_setdata(DisplayState
*ds
)
1490 /* We don't have to do anything */
1493 static void vnc_colordepth(VncState
*vs
)
1495 if (vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
1496 /* Sending a WMVi message to notify the client*/
1497 vnc_write_u8(vs
, 0); /* msg id */
1498 vnc_write_u8(vs
, 0);
1499 vnc_write_u16(vs
, 1); /* number of rects */
1500 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
),
1501 ds_get_height(vs
->ds
), VNC_ENCODING_WMVi
);
1502 pixel_format_message(vs
);
1505 set_pixel_conversion(vs
);
1509 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
1519 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
1520 read_u8(data
, 6), read_u8(data
, 7),
1521 read_u16(data
, 8), read_u16(data
, 10),
1522 read_u16(data
, 12), read_u8(data
, 14),
1523 read_u8(data
, 15), read_u8(data
, 16));
1530 limit
= read_u16(data
, 2);
1532 return 4 + (limit
* 4);
1534 limit
= read_u16(data
, 2);
1536 for (i
= 0; i
< limit
; i
++) {
1537 int32_t val
= read_s32(data
, 4 + (i
* 4));
1538 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
1541 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
1547 framebuffer_update_request(vs
,
1548 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
1549 read_u16(data
, 6), read_u16(data
, 8));
1555 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
1561 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
1568 uint32_t dlen
= read_u32(data
, 4);
1573 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
1579 switch (read_u8(data
, 1)) {
1584 ext_key_event(vs
, read_u16(data
, 2),
1585 read_u32(data
, 4), read_u32(data
, 8));
1591 switch (read_u16 (data
, 2)) {
1601 switch (read_u8(data
, 4)) {
1602 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
1603 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
1604 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
1605 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
1606 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
1607 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
1609 printf("Invalid audio format %d\n", read_u8(data
, 4));
1610 vnc_client_error(vs
);
1613 vs
->as
.nchannels
= read_u8(data
, 5);
1614 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
1615 printf("Invalid audio channel coount %d\n",
1617 vnc_client_error(vs
);
1620 vs
->as
.freq
= read_u32(data
, 6);
1623 printf ("Invalid audio message %d\n", read_u8(data
, 4));
1624 vnc_client_error(vs
);
1630 printf("Msg: %d\n", read_u16(data
, 0));
1631 vnc_client_error(vs
);
1636 printf("Msg: %d\n", data
[0]);
1637 vnc_client_error(vs
);
1641 vnc_read_when(vs
, protocol_client_msg
, 1);
1645 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
1650 vnc_write_u16(vs
, ds_get_width(vs
->ds
));
1651 vnc_write_u16(vs
, ds_get_height(vs
->ds
));
1653 pixel_format_message(vs
);
1656 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
1658 size
= snprintf(buf
, sizeof(buf
), "QEMU");
1660 vnc_write_u32(vs
, size
);
1661 vnc_write(vs
, buf
, size
);
1664 vnc_read_when(vs
, protocol_client_msg
, 1);
1669 static void make_challenge(VncState
*vs
)
1673 srand(time(NULL
)+getpid()+getpid()*987654+rand());
1675 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
1676 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
1679 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
1681 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
1683 unsigned char key
[8];
1685 if (!vs
->vd
->password
|| !vs
->vd
->password
[0]) {
1686 VNC_DEBUG("No password configured on server");
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
);
1698 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
1700 /* Calculate the expected challenge response */
1701 pwlen
= strlen(vs
->vd
->password
);
1702 for (i
=0; i
<sizeof(key
); i
++)
1703 key
[i
] = i
<pwlen
? vs
->vd
->password
[i
] : 0;
1705 for (j
= 0; j
< VNC_AUTH_CHALLENGE_SIZE
; j
+= 8)
1706 des(response
+j
, response
+j
);
1708 /* Compare expected vs actual challenge response */
1709 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
1710 VNC_DEBUG("Client challenge reponse did not match\n");
1711 vnc_write_u32(vs
, 1); /* Reject auth */
1712 if (vs
->minor
>= 8) {
1713 static const char err
[] = "Authentication failed";
1714 vnc_write_u32(vs
, sizeof(err
));
1715 vnc_write(vs
, err
, sizeof(err
));
1718 vnc_client_error(vs
);
1720 VNC_DEBUG("Accepting VNC challenge response\n");
1721 vnc_write_u32(vs
, 0); /* Accept auth */
1724 vnc_read_when(vs
, protocol_client_init
, 1);
1729 static int start_auth_vnc(VncState
*vs
)
1732 /* Send client a 'random' challenge */
1733 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
1736 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
1741 #ifdef CONFIG_VNC_TLS
1742 #define DH_BITS 1024
1743 static gnutls_dh_params_t dh_params
;
1745 static int vnc_tls_initialize(void)
1747 static int tlsinitialized
= 0;
1752 if (gnutls_global_init () < 0)
1755 /* XXX ought to re-generate diffie-hellmen params periodically */
1756 if (gnutls_dh_params_init (&dh_params
) < 0)
1758 if (gnutls_dh_params_generate2 (dh_params
, DH_BITS
) < 0)
1761 #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
1762 gnutls_global_set_log_level(10);
1763 gnutls_global_set_log_function(vnc_debug_gnutls_log
);
1771 static gnutls_anon_server_credentials
vnc_tls_initialize_anon_cred(void)
1773 gnutls_anon_server_credentials anon_cred
;
1776 if ((ret
= gnutls_anon_allocate_server_credentials(&anon_cred
)) < 0) {
1777 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1781 gnutls_anon_set_server_dh_params(anon_cred
, dh_params
);
1787 static gnutls_certificate_credentials_t
vnc_tls_initialize_x509_cred(VncState
*vs
)
1789 gnutls_certificate_credentials_t x509_cred
;
1792 if (!vs
->vd
->x509cacert
) {
1793 VNC_DEBUG("No CA x509 certificate specified\n");
1796 if (!vs
->vd
->x509cert
) {
1797 VNC_DEBUG("No server x509 certificate specified\n");
1800 if (!vs
->vd
->x509key
) {
1801 VNC_DEBUG("No server private key specified\n");
1805 if ((ret
= gnutls_certificate_allocate_credentials(&x509_cred
)) < 0) {
1806 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1809 if ((ret
= gnutls_certificate_set_x509_trust_file(x509_cred
,
1811 GNUTLS_X509_FMT_PEM
)) < 0) {
1812 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret
));
1813 gnutls_certificate_free_credentials(x509_cred
);
1817 if ((ret
= gnutls_certificate_set_x509_key_file (x509_cred
,
1820 GNUTLS_X509_FMT_PEM
)) < 0) {
1821 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret
));
1822 gnutls_certificate_free_credentials(x509_cred
);
1826 if (vs
->vd
->x509cacrl
) {
1827 if ((ret
= gnutls_certificate_set_x509_crl_file(x509_cred
,
1829 GNUTLS_X509_FMT_PEM
)) < 0) {
1830 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret
));
1831 gnutls_certificate_free_credentials(x509_cred
);
1836 gnutls_certificate_set_dh_params (x509_cred
, dh_params
);
1841 static int vnc_validate_certificate(struct VncState
*vs
)
1844 unsigned int status
;
1845 const gnutls_datum_t
*certs
;
1846 unsigned int nCerts
, i
;
1849 VNC_DEBUG("Validating client certificate\n");
1850 if ((ret
= gnutls_certificate_verify_peers2 (vs
->tls_session
, &status
)) < 0) {
1851 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret
));
1855 if ((now
= time(NULL
)) == ((time_t)-1)) {
1860 if (status
& GNUTLS_CERT_INVALID
)
1861 VNC_DEBUG("The certificate is not trusted.\n");
1863 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
1864 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1866 if (status
& GNUTLS_CERT_REVOKED
)
1867 VNC_DEBUG("The certificate has been revoked.\n");
1869 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1870 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1874 VNC_DEBUG("Certificate is valid!\n");
1877 /* Only support x509 for now */
1878 if (gnutls_certificate_type_get(vs
->tls_session
) != GNUTLS_CRT_X509
)
1881 if (!(certs
= gnutls_certificate_get_peers(vs
->tls_session
, &nCerts
)))
1884 for (i
= 0 ; i
< nCerts
; i
++) {
1885 gnutls_x509_crt_t cert
;
1886 VNC_DEBUG ("Checking certificate chain %d\n", i
);
1887 if (gnutls_x509_crt_init (&cert
) < 0)
1890 if (gnutls_x509_crt_import(cert
, &certs
[i
], GNUTLS_X509_FMT_DER
) < 0) {
1891 gnutls_x509_crt_deinit (cert
);
1895 if (gnutls_x509_crt_get_expiration_time (cert
) < now
) {
1896 VNC_DEBUG("The certificate has expired\n");
1897 gnutls_x509_crt_deinit (cert
);
1901 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1902 VNC_DEBUG("The certificate is not yet activated\n");
1903 gnutls_x509_crt_deinit (cert
);
1907 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1908 VNC_DEBUG("The certificate is not yet activated\n");
1909 gnutls_x509_crt_deinit (cert
);
1913 gnutls_x509_crt_deinit (cert
);
1920 static int start_auth_vencrypt_subauth(VncState
*vs
)
1922 switch (vs
->vd
->subauth
) {
1923 case VNC_AUTH_VENCRYPT_TLSNONE
:
1924 case VNC_AUTH_VENCRYPT_X509NONE
:
1925 VNC_DEBUG("Accept TLS auth none\n");
1926 vnc_write_u32(vs
, 0); /* Accept auth completion */
1927 vnc_read_when(vs
, protocol_client_init
, 1);
1930 case VNC_AUTH_VENCRYPT_TLSVNC
:
1931 case VNC_AUTH_VENCRYPT_X509VNC
:
1932 VNC_DEBUG("Start TLS auth VNC\n");
1933 return start_auth_vnc(vs
);
1935 default: /* Should not be possible, but just in case */
1936 VNC_DEBUG("Reject auth %d\n", vs
->vd
->auth
);
1937 vnc_write_u8(vs
, 1);
1938 if (vs
->minor
>= 8) {
1939 static const char err
[] = "Unsupported authentication type";
1940 vnc_write_u32(vs
, sizeof(err
));
1941 vnc_write(vs
, err
, sizeof(err
));
1943 vnc_client_error(vs
);
1949 static void vnc_handshake_io(void *opaque
);
1951 static int vnc_continue_handshake(struct VncState
*vs
) {
1954 if ((ret
= gnutls_handshake(vs
->tls_session
)) < 0) {
1955 if (!gnutls_error_is_fatal(ret
)) {
1956 VNC_DEBUG("Handshake interrupted (blocking)\n");
1957 if (!gnutls_record_get_direction(vs
->tls_session
))
1958 qemu_set_fd_handler(vs
->csock
, vnc_handshake_io
, NULL
, vs
);
1960 qemu_set_fd_handler(vs
->csock
, NULL
, vnc_handshake_io
, vs
);
1963 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret
));
1964 vnc_client_error(vs
);
1968 if (vs
->vd
->x509verify
) {
1969 if (vnc_validate_certificate(vs
) < 0) {
1970 VNC_DEBUG("Client verification failed\n");
1971 vnc_client_error(vs
);
1974 VNC_DEBUG("Client verification passed\n");
1978 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1979 vs
->wiremode
= VNC_WIREMODE_TLS
;
1980 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
1982 return start_auth_vencrypt_subauth(vs
);
1985 static void vnc_handshake_io(void *opaque
) {
1986 struct VncState
*vs
= (struct VncState
*)opaque
;
1988 VNC_DEBUG("Handshake IO continue\n");
1989 vnc_continue_handshake(vs
);
1992 #define NEED_X509_AUTH(vs) \
1993 ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1994 (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1995 (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1998 static int vnc_start_tls(struct VncState
*vs
) {
1999 static const int cert_type_priority
[] = { GNUTLS_CRT_X509
, 0 };
2000 static const int protocol_priority
[]= { GNUTLS_TLS1_1
, GNUTLS_TLS1_0
, GNUTLS_SSL3
, 0 };
2001 static const int kx_anon
[] = {GNUTLS_KX_ANON_DH
, 0};
2002 static const int kx_x509
[] = {GNUTLS_KX_DHE_DSS
, GNUTLS_KX_RSA
, GNUTLS_KX_DHE_RSA
, GNUTLS_KX_SRP
, 0};
2004 VNC_DEBUG("Do TLS setup\n");
2005 if (vnc_tls_initialize() < 0) {
2006 VNC_DEBUG("Failed to init TLS\n");
2007 vnc_client_error(vs
);
2010 if (vs
->tls_session
== NULL
) {
2011 if (gnutls_init(&vs
->tls_session
, GNUTLS_SERVER
) < 0) {
2012 vnc_client_error(vs
);
2016 if (gnutls_set_default_priority(vs
->tls_session
) < 0) {
2017 gnutls_deinit(vs
->tls_session
);
2018 vs
->tls_session
= NULL
;
2019 vnc_client_error(vs
);
2023 if (gnutls_kx_set_priority(vs
->tls_session
, NEED_X509_AUTH(vs
) ? kx_x509
: kx_anon
) < 0) {
2024 gnutls_deinit(vs
->tls_session
);
2025 vs
->tls_session
= NULL
;
2026 vnc_client_error(vs
);
2030 if (gnutls_certificate_type_set_priority(vs
->tls_session
, cert_type_priority
) < 0) {
2031 gnutls_deinit(vs
->tls_session
);
2032 vs
->tls_session
= NULL
;
2033 vnc_client_error(vs
);
2037 if (gnutls_protocol_set_priority(vs
->tls_session
, protocol_priority
) < 0) {
2038 gnutls_deinit(vs
->tls_session
);
2039 vs
->tls_session
= NULL
;
2040 vnc_client_error(vs
);
2044 if (NEED_X509_AUTH(vs
)) {
2045 gnutls_certificate_server_credentials x509_cred
= vnc_tls_initialize_x509_cred(vs
);
2047 gnutls_deinit(vs
->tls_session
);
2048 vs
->tls_session
= NULL
;
2049 vnc_client_error(vs
);
2052 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_CERTIFICATE
, x509_cred
) < 0) {
2053 gnutls_deinit(vs
->tls_session
);
2054 vs
->tls_session
= NULL
;
2055 gnutls_certificate_free_credentials(x509_cred
);
2056 vnc_client_error(vs
);
2059 if (vs
->vd
->x509verify
) {
2060 VNC_DEBUG("Requesting a client certificate\n");
2061 gnutls_certificate_server_set_request (vs
->tls_session
, GNUTLS_CERT_REQUEST
);
2065 gnutls_anon_server_credentials anon_cred
= vnc_tls_initialize_anon_cred();
2067 gnutls_deinit(vs
->tls_session
);
2068 vs
->tls_session
= NULL
;
2069 vnc_client_error(vs
);
2072 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_ANON
, anon_cred
) < 0) {
2073 gnutls_deinit(vs
->tls_session
);
2074 vs
->tls_session
= NULL
;
2075 gnutls_anon_free_server_credentials(anon_cred
);
2076 vnc_client_error(vs
);
2081 gnutls_transport_set_ptr(vs
->tls_session
, (gnutls_transport_ptr_t
)vs
);
2082 gnutls_transport_set_push_function(vs
->tls_session
, vnc_tls_push
);
2083 gnutls_transport_set_pull_function(vs
->tls_session
, vnc_tls_pull
);
2086 VNC_DEBUG("Start TLS handshake process\n");
2087 return vnc_continue_handshake(vs
);
2090 static int protocol_client_vencrypt_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2092 int auth
= read_u32(data
, 0);
2094 if (auth
!= vs
->vd
->subauth
) {
2095 VNC_DEBUG("Rejecting auth %d\n", auth
);
2096 vnc_write_u8(vs
, 0); /* Reject auth */
2098 vnc_client_error(vs
);
2100 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth
);
2101 vnc_write_u8(vs
, 1); /* Accept auth */
2104 if (vnc_start_tls(vs
) < 0) {
2105 VNC_DEBUG("Failed to complete TLS\n");
2109 if (vs
->wiremode
== VNC_WIREMODE_TLS
) {
2110 VNC_DEBUG("Starting VeNCrypt subauth\n");
2111 return start_auth_vencrypt_subauth(vs
);
2113 VNC_DEBUG("TLS handshake blocked\n");
2120 static int protocol_client_vencrypt_init(VncState
*vs
, uint8_t *data
, size_t len
)
2124 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data
[0], (int)data
[1]);
2125 vnc_write_u8(vs
, 1); /* Reject version */
2127 vnc_client_error(vs
);
2129 VNC_DEBUG("Sending allowed auth %d\n", vs
->vd
->subauth
);
2130 vnc_write_u8(vs
, 0); /* Accept version */
2131 vnc_write_u8(vs
, 1); /* Number of sub-auths */
2132 vnc_write_u32(vs
, vs
->vd
->subauth
); /* The supported auth */
2134 vnc_read_when(vs
, protocol_client_vencrypt_auth
, 4);
2139 static int start_auth_vencrypt(VncState
*vs
)
2141 /* Send VeNCrypt version 0.2 */
2142 vnc_write_u8(vs
, 0);
2143 vnc_write_u8(vs
, 2);
2145 vnc_read_when(vs
, protocol_client_vencrypt_init
, 2);
2148 #endif /* CONFIG_VNC_TLS */
2150 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2152 /* We only advertise 1 auth scheme at a time, so client
2153 * must pick the one we sent. Verify this */
2154 if (data
[0] != vs
->vd
->auth
) { /* Reject auth */
2155 VNC_DEBUG("Reject auth %d\n", (int)data
[0]);
2156 vnc_write_u32(vs
, 1);
2157 if (vs
->minor
>= 8) {
2158 static const char err
[] = "Authentication failed";
2159 vnc_write_u32(vs
, sizeof(err
));
2160 vnc_write(vs
, err
, sizeof(err
));
2162 vnc_client_error(vs
);
2163 } else { /* Accept requested auth */
2164 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2165 switch (vs
->vd
->auth
) {
2167 VNC_DEBUG("Accept auth none\n");
2168 if (vs
->minor
>= 8) {
2169 vnc_write_u32(vs
, 0); /* Accept auth completion */
2172 vnc_read_when(vs
, protocol_client_init
, 1);
2176 VNC_DEBUG("Start VNC auth\n");
2177 return start_auth_vnc(vs
);
2179 #ifdef CONFIG_VNC_TLS
2180 case VNC_AUTH_VENCRYPT
:
2181 VNC_DEBUG("Accept VeNCrypt auth\n");;
2182 return start_auth_vencrypt(vs
);
2183 #endif /* CONFIG_VNC_TLS */
2185 default: /* Should not be possible, but just in case */
2186 VNC_DEBUG("Reject auth %d\n", vs
->vd
->auth
);
2187 vnc_write_u8(vs
, 1);
2188 if (vs
->minor
>= 8) {
2189 static const char err
[] = "Authentication failed";
2190 vnc_write_u32(vs
, sizeof(err
));
2191 vnc_write(vs
, err
, sizeof(err
));
2193 vnc_client_error(vs
);
2199 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2203 memcpy(local
, version
, 12);
2206 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2207 VNC_DEBUG("Malformed protocol version %s\n", local
);
2208 vnc_client_error(vs
);
2211 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2212 if (vs
->major
!= 3 ||
2218 VNC_DEBUG("Unsupported client version\n");
2219 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2221 vnc_client_error(vs
);
2224 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2225 * as equivalent to v3.3 by servers
2227 if (vs
->minor
== 4 || vs
->minor
== 5)
2230 if (vs
->minor
== 3) {
2231 if (vs
->vd
->auth
== VNC_AUTH_NONE
) {
2232 VNC_DEBUG("Tell client auth none\n");
2233 vnc_write_u32(vs
, vs
->vd
->auth
);
2235 vnc_read_when(vs
, protocol_client_init
, 1);
2236 } else if (vs
->vd
->auth
== VNC_AUTH_VNC
) {
2237 VNC_DEBUG("Tell client VNC auth\n");
2238 vnc_write_u32(vs
, vs
->vd
->auth
);
2242 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->vd
->auth
);
2243 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2245 vnc_client_error(vs
);
2248 VNC_DEBUG("Telling client we support auth %d\n", vs
->vd
->auth
);
2249 vnc_write_u8(vs
, 1); /* num auth */
2250 vnc_write_u8(vs
, vs
->vd
->auth
);
2251 vnc_read_when(vs
, protocol_client_auth
, 1);
2258 static void vnc_connect(VncDisplay
*vd
, int csock
)
2260 VncState
*vs
= qemu_mallocz(sizeof(VncState
));
2263 VNC_DEBUG("New client on socket %d\n", csock
);
2265 socket_set_nonblock(vs
->csock
);
2266 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
2270 vs
->timer
= qemu_new_timer(rt_clock
, vnc_update_client
, vs
);
2274 vs
->as
.freq
= 44100;
2275 vs
->as
.nchannels
= 2;
2276 vs
->as
.fmt
= AUD_FMT_S16
;
2277 vs
->as
.endianness
= 0;
2280 vnc_write(vs
, "RFB 003.008\n", 12);
2282 vnc_read_when(vs
, protocol_version
, 12);
2283 memset(vs
->old_data
, 0, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
2284 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
2285 vnc_update_client(vs
);
2288 vs
->next
= vd
->clients
;
2292 static void vnc_listen_read(void *opaque
)
2294 VncDisplay
*vs
= opaque
;
2295 struct sockaddr_in addr
;
2296 socklen_t addrlen
= sizeof(addr
);
2301 int csock
= accept(vs
->lsock
, (struct sockaddr
*)&addr
, &addrlen
);
2303 vnc_connect(vs
, csock
);
2307 void vnc_display_init(DisplayState
*ds
)
2309 VncDisplay
*vs
= qemu_mallocz(sizeof(*vs
));
2311 dcl
= qemu_mallocz(sizeof(DisplayChangeListener
));
2321 if (keyboard_layout
)
2322 vs
->kbd_layout
= init_keyboard_layout(keyboard_layout
);
2324 vs
->kbd_layout
= init_keyboard_layout("en-us");
2326 if (!vs
->kbd_layout
)
2329 dcl
->dpy_copy
= vnc_dpy_copy
;
2330 dcl
->dpy_update
= vnc_dpy_update
;
2331 dcl
->dpy_resize
= vnc_dpy_resize
;
2332 dcl
->dpy_setdata
= vnc_dpy_setdata
;
2333 register_displaychangelistener(ds
, dcl
);
2336 #ifdef CONFIG_VNC_TLS
2337 static int vnc_set_x509_credential(VncDisplay
*vs
,
2338 const char *certdir
,
2339 const char *filename
,
2350 *cred
= qemu_malloc(strlen(certdir
) + strlen(filename
) + 2);
2352 strcpy(*cred
, certdir
);
2354 strcat(*cred
, filename
);
2356 VNC_DEBUG("Check %s\n", *cred
);
2357 if (stat(*cred
, &sb
) < 0) {
2360 if (ignoreMissing
&& errno
== ENOENT
)
2368 static int vnc_set_x509_credential_dir(VncDisplay
*vs
,
2369 const char *certdir
)
2371 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CERT_FILE
, &vs
->x509cacert
, 0) < 0)
2373 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CRL_FILE
, &vs
->x509cacrl
, 1) < 0)
2375 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_CERT_FILE
, &vs
->x509cert
, 0) < 0)
2377 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_KEY_FILE
, &vs
->x509key
, 0) < 0)
2383 qemu_free(vs
->x509cacert
);
2384 qemu_free(vs
->x509cacrl
);
2385 qemu_free(vs
->x509cert
);
2386 qemu_free(vs
->x509key
);
2387 vs
->x509cacert
= vs
->x509cacrl
= vs
->x509cert
= vs
->x509key
= NULL
;
2390 #endif /* CONFIG_VNC_TLS */
2392 void vnc_display_close(DisplayState
*ds
)
2394 VncDisplay
*vs
= ds
? (VncDisplay
*)ds
->opaque
: vnc_display
;
2399 qemu_free(vs
->display
);
2402 if (vs
->lsock
!= -1) {
2403 qemu_set_fd_handler2(vs
->lsock
, NULL
, NULL
, NULL
, NULL
);
2407 vs
->auth
= VNC_AUTH_INVALID
;
2408 #ifdef CONFIG_VNC_TLS
2409 vs
->subauth
= VNC_AUTH_INVALID
;
2414 int vnc_display_password(DisplayState
*ds
, const char *password
)
2416 VncDisplay
*vs
= ds
? (VncDisplay
*)ds
->opaque
: vnc_display
;
2419 qemu_free(vs
->password
);
2420 vs
->password
= NULL
;
2422 if (password
&& password
[0]) {
2423 if (!(vs
->password
= qemu_strdup(password
)))
2430 int vnc_display_open(DisplayState
*ds
, const char *display
)
2432 VncDisplay
*vs
= ds
? (VncDisplay
*)ds
->opaque
: vnc_display
;
2433 const char *options
;
2437 #ifdef CONFIG_VNC_TLS
2438 int tls
= 0, x509
= 0;
2443 vnc_display_close(ds
);
2444 if (strcmp(display
, "none") == 0)
2447 if (!(vs
->display
= strdup(display
)))
2451 while ((options
= strchr(options
, ','))) {
2453 if (strncmp(options
, "password", 8) == 0) {
2454 password
= 1; /* Require password auth */
2455 } else if (strncmp(options
, "reverse", 7) == 0) {
2457 } else if (strncmp(options
, "to=", 3) == 0) {
2458 to_port
= atoi(options
+3) + 5900;
2459 #ifdef CONFIG_VNC_TLS
2460 } else if (strncmp(options
, "tls", 3) == 0) {
2461 tls
= 1; /* Require TLS */
2462 } else if (strncmp(options
, "x509", 4) == 0) {
2464 x509
= 1; /* Require x509 certificates */
2465 if (strncmp(options
, "x509verify", 10) == 0)
2466 vs
->x509verify
= 1; /* ...and verify client certs */
2468 /* Now check for 'x509=/some/path' postfix
2469 * and use that to setup x509 certificate/key paths */
2470 start
= strchr(options
, '=');
2471 end
= strchr(options
, ',');
2472 if (start
&& (!end
|| (start
< end
))) {
2473 int len
= end
? end
-(start
+1) : strlen(start
+1);
2474 char *path
= qemu_strndup(start
+ 1, len
);
2476 VNC_DEBUG("Trying certificate path '%s'\n", path
);
2477 if (vnc_set_x509_credential_dir(vs
, path
) < 0) {
2478 fprintf(stderr
, "Failed to find x509 certificates/keys in %s\n", path
);
2480 qemu_free(vs
->display
);
2486 fprintf(stderr
, "No certificate path provided\n");
2487 qemu_free(vs
->display
);
2496 #ifdef CONFIG_VNC_TLS
2498 vs
->auth
= VNC_AUTH_VENCRYPT
;
2500 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2501 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
2503 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2504 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
2508 VNC_DEBUG("Initializing VNC server with password auth\n");
2509 vs
->auth
= VNC_AUTH_VNC
;
2510 #ifdef CONFIG_VNC_TLS
2511 vs
->subauth
= VNC_AUTH_INVALID
;
2515 #ifdef CONFIG_VNC_TLS
2517 vs
->auth
= VNC_AUTH_VENCRYPT
;
2519 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2520 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
2522 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2523 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
2527 VNC_DEBUG("Initializing VNC server with no auth\n");
2528 vs
->auth
= VNC_AUTH_NONE
;
2529 #ifdef CONFIG_VNC_TLS
2530 vs
->subauth
= VNC_AUTH_INVALID
;
2536 /* connect to viewer */
2537 if (strncmp(display
, "unix:", 5) == 0)
2538 vs
->lsock
= unix_connect(display
+5);
2540 vs
->lsock
= inet_connect(display
, SOCK_STREAM
);
2541 if (-1 == vs
->lsock
) {
2546 int csock
= vs
->lsock
;
2548 vnc_connect(vs
, csock
);
2553 /* listen for connects */
2555 dpy
= qemu_malloc(256);
2556 if (strncmp(display
, "unix:", 5) == 0) {
2557 pstrcpy(dpy
, 256, "unix:");
2558 vs
->lsock
= unix_listen(display
+5, dpy
+5, 256-5);
2560 vs
->lsock
= inet_listen(display
, dpy
, 256, SOCK_STREAM
, 5900);
2562 if (-1 == vs
->lsock
) {
2570 return qemu_set_fd_handler2(vs
->lsock
, NULL
, vnc_listen_read
, NULL
, vs
);