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
100 uint32_t dirty_row
[VNC_MAX_HEIGHT
][VNC_DIRTY_WORDS
];
107 uint32_t vnc_encoding
;
108 uint8_t tight_quality
;
109 uint8_t tight_compression
;
117 #ifdef CONFIG_VNC_TLS
126 char challenge
[VNC_AUTH_CHALLENGE_SIZE
];
128 #ifdef CONFIG_VNC_TLS
130 gnutls_session_t tls_session
;
135 kbd_layout_t
*kbd_layout
;
136 /* current output mode information */
137 VncWritePixels
*write_pixels
;
138 VncSendHextileTile
*send_hextile_tile
;
139 DisplaySurface clientds
, serverds
;
141 CaptureVoiceOut
*audio_cap
;
142 struct audsettings as
;
144 VncReadEvent
*read_handler
;
145 size_t read_handler_expect
;
147 uint8_t modifiers_state
[256];
151 z_stream zlib_stream
[4];
154 static VncState
*vnc_state
; /* needed for info vnc */
155 static DisplayChangeListener
*dcl
;
157 void do_info_vnc(void)
159 if (vnc_state
== NULL
|| vnc_state
->display
== NULL
)
160 term_printf("VNC server disabled\n");
162 term_printf("VNC server active on: ");
163 term_print_filename(vnc_state
->display
);
166 if (vnc_state
->csock
== -1)
167 term_printf("No client connected\n");
169 term_printf("Client connected\n");
173 static inline uint32_t vnc_has_feature(VncState
*vs
, int feature
) {
174 return (vs
->features
& (1 << feature
));
178 1) Get the queue working for IO.
179 2) there is some weirdness when using the -S option (the screen is grey
180 and not totally invalidated
181 3) resolutions > 1024
184 static void vnc_write(VncState
*vs
, const void *data
, size_t len
);
185 static void vnc_write_u32(VncState
*vs
, uint32_t value
);
186 static void vnc_write_s32(VncState
*vs
, int32_t value
);
187 static void vnc_write_u16(VncState
*vs
, uint16_t value
);
188 static void vnc_write_u8(VncState
*vs
, uint8_t value
);
189 static void vnc_flush(VncState
*vs
);
190 static void vnc_update_client(void *opaque
);
191 static void vnc_client_read(void *opaque
);
193 static void vnc_colordepth(DisplayState
*ds
);
195 static inline void vnc_set_bit(uint32_t *d
, int k
)
197 d
[k
>> 5] |= 1 << (k
& 0x1f);
200 static inline void vnc_clear_bit(uint32_t *d
, int k
)
202 d
[k
>> 5] &= ~(1 << (k
& 0x1f));
205 static inline void vnc_set_bits(uint32_t *d
, int n
, int nb_words
)
215 d
[j
++] = (1 << n
) - 1;
220 static inline int vnc_get_bit(const uint32_t *d
, int k
)
222 return (d
[k
>> 5] >> (k
& 0x1f)) & 1;
225 static inline int vnc_and_bits(const uint32_t *d1
, const uint32_t *d2
,
229 for(i
= 0; i
< nb_words
; i
++) {
230 if ((d1
[i
] & d2
[i
]) != 0)
236 static void vnc_dpy_update(DisplayState
*ds
, int x
, int y
, int w
, int h
)
238 VncState
*vs
= ds
->opaque
;
243 /* round x down to ensure the loop only spans one 16-pixel block per,
244 iteration. otherwise, if (x % 16) != 0, the last iteration may span
245 two 16-pixel blocks but we only mark the first as dirty
250 x
= MIN(x
, vs
->serverds
.width
);
251 y
= MIN(y
, vs
->serverds
.height
);
252 w
= MIN(x
+ w
, vs
->serverds
.width
) - x
;
253 h
= MIN(h
, vs
->serverds
.height
);
256 for (i
= 0; i
< w
; i
+= 16)
257 vnc_set_bit(vs
->dirty_row
[y
], (x
+ i
) / 16);
260 static void vnc_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
,
263 vnc_write_u16(vs
, x
);
264 vnc_write_u16(vs
, y
);
265 vnc_write_u16(vs
, w
);
266 vnc_write_u16(vs
, h
);
268 vnc_write_s32(vs
, encoding
);
271 static void buffer_reserve(Buffer
*buffer
, size_t len
)
273 if ((buffer
->capacity
- buffer
->offset
) < len
) {
274 buffer
->capacity
+= (len
+ 1024);
275 buffer
->buffer
= qemu_realloc(buffer
->buffer
, buffer
->capacity
);
276 if (buffer
->buffer
== NULL
) {
277 fprintf(stderr
, "vnc: out of memory\n");
283 static int buffer_empty(Buffer
*buffer
)
285 return buffer
->offset
== 0;
288 static uint8_t *buffer_end(Buffer
*buffer
)
290 return buffer
->buffer
+ buffer
->offset
;
293 static void buffer_reset(Buffer
*buffer
)
298 static void buffer_append(Buffer
*buffer
, const void *data
, size_t len
)
300 memcpy(buffer
->buffer
+ buffer
->offset
, data
, len
);
301 buffer
->offset
+= len
;
304 static void vnc_dpy_resize(DisplayState
*ds
)
307 VncState
*vs
= ds
->opaque
;
309 vs
->old_data
= qemu_realloc(vs
->old_data
, ds_get_linesize(ds
) * ds_get_height(ds
));
311 if (vs
->old_data
== NULL
) {
312 fprintf(stderr
, "vnc: memory allocation failed\n");
316 if (ds_get_bytes_per_pixel(ds
) != vs
->serverds
.pf
.bytes_per_pixel
)
317 console_color_init(ds
);
319 size_changed
= ds_get_width(ds
) != vs
->serverds
.width
||
320 ds_get_height(ds
) != vs
->serverds
.height
;
321 vs
->serverds
= *(ds
->surface
);
323 if (vs
->csock
!= -1 && vnc_has_feature(vs
, VNC_FEATURE_RESIZE
)) {
324 vnc_write_u8(vs
, 0); /* msg id */
326 vnc_write_u16(vs
, 1); /* number of rects */
327 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(ds
), ds_get_height(ds
),
328 VNC_ENCODING_DESKTOPRESIZE
);
333 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
334 memset(vs
->old_data
, 42, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
338 static void vnc_write_pixels_copy(VncState
*vs
, void *pixels
, int size
)
340 vnc_write(vs
, pixels
, size
);
343 /* slowest but generic code. */
344 static void vnc_convert_pixel(VncState
*vs
, uint8_t *buf
, uint32_t v
)
348 r
= ((((v
& vs
->serverds
.pf
.rmask
) >> vs
->serverds
.pf
.rshift
) << vs
->clientds
.pf
.rbits
) >>
349 vs
->serverds
.pf
.rbits
);
350 g
= ((((v
& vs
->serverds
.pf
.gmask
) >> vs
->serverds
.pf
.gshift
) << vs
->clientds
.pf
.gbits
) >>
351 vs
->serverds
.pf
.gbits
);
352 b
= ((((v
& vs
->serverds
.pf
.bmask
) >> vs
->serverds
.pf
.bshift
) << vs
->clientds
.pf
.bbits
) >>
353 vs
->serverds
.pf
.bbits
);
354 v
= (r
<< vs
->clientds
.pf
.rshift
) |
355 (g
<< vs
->clientds
.pf
.gshift
) |
356 (b
<< vs
->clientds
.pf
.bshift
);
357 switch(vs
->clientds
.pf
.bytes_per_pixel
) {
362 if (vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) {
372 if (vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) {
387 static void vnc_write_pixels_generic(VncState
*vs
, void *pixels1
, int size
)
391 if (vs
->serverds
.pf
.bytes_per_pixel
== 4) {
392 uint32_t *pixels
= pixels1
;
395 for(i
= 0; i
< n
; i
++) {
396 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
397 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
399 } else if (vs
->serverds
.pf
.bytes_per_pixel
== 2) {
400 uint16_t *pixels
= pixels1
;
403 for(i
= 0; i
< n
; i
++) {
404 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
405 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
407 } else if (vs
->serverds
.pf
.bytes_per_pixel
== 1) {
408 uint8_t *pixels
= pixels1
;
411 for(i
= 0; i
< n
; i
++) {
412 vnc_convert_pixel(vs
, buf
, pixels
[i
]);
413 vnc_write(vs
, buf
, vs
->clientds
.pf
.bytes_per_pixel
);
416 fprintf(stderr
, "vnc_write_pixels_generic: VncState color depth not supported\n");
420 static void send_framebuffer_update_raw(VncState
*vs
, int x
, int y
, int w
, int h
)
425 row
= ds_get_data(vs
->ds
) + y
* ds_get_linesize(vs
->ds
) + x
* ds_get_bytes_per_pixel(vs
->ds
);
426 for (i
= 0; i
< h
; i
++) {
427 vs
->write_pixels(vs
, row
, w
* ds_get_bytes_per_pixel(vs
->ds
));
428 row
+= ds_get_linesize(vs
->ds
);
432 static void hextile_enc_cord(uint8_t *ptr
, int x
, int y
, int w
, int h
)
434 ptr
[0] = ((x
& 0x0F) << 4) | (y
& 0x0F);
435 ptr
[1] = (((w
- 1) & 0x0F) << 4) | ((h
- 1) & 0x0F);
439 #include "vnchextile.h"
443 #include "vnchextile.h"
447 #include "vnchextile.h"
452 #include "vnchextile.h"
458 #include "vnchextile.h"
464 #include "vnchextile.h"
468 static void send_framebuffer_update_hextile(VncState
*vs
, int x
, int y
, int w
, int h
)
472 uint8_t *last_fg
, *last_bg
;
474 last_fg
= (uint8_t *) qemu_malloc(vs
->serverds
.pf
.bytes_per_pixel
);
475 last_bg
= (uint8_t *) qemu_malloc(vs
->serverds
.pf
.bytes_per_pixel
);
477 for (j
= y
; j
< (y
+ h
); j
+= 16) {
478 for (i
= x
; i
< (x
+ w
); i
+= 16) {
479 vs
->send_hextile_tile(vs
, i
, j
,
480 MIN(16, x
+ w
- i
), MIN(16, y
+ h
- j
),
481 last_bg
, last_fg
, &has_bg
, &has_fg
);
489 static void vnc_zlib_init(VncState
*vs
)
492 for (i
=0; i
<(sizeof(vs
->zlib_stream
) / sizeof(z_stream
)); i
++)
493 vs
->zlib_stream
[i
].opaque
= NULL
;
496 static void vnc_zlib_start(VncState
*vs
)
498 buffer_reset(&vs
->zlib
);
500 // make the output buffer be the zlib buffer, so we can compress it later
501 vs
->zlib_tmp
= vs
->output
;
502 vs
->output
= vs
->zlib
;
505 static int vnc_zlib_stop(VncState
*vs
, int stream_id
)
507 z_streamp zstream
= &vs
->zlib_stream
[stream_id
];
510 // switch back to normal output/zlib buffers
511 vs
->zlib
= vs
->output
;
512 vs
->output
= vs
->zlib_tmp
;
514 // compress the zlib buffer
516 // initialize the stream
517 // XXX need one stream per session
518 if (zstream
->opaque
!= vs
) {
521 VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id
);
522 VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream
->opaque
, vs
);
523 zstream
->zalloc
= Z_NULL
;
524 zstream
->zfree
= Z_NULL
;
526 err
= deflateInit2(zstream
, vs
->tight_compression
, Z_DEFLATED
, MAX_WBITS
,
527 MAX_MEM_LEVEL
, Z_DEFAULT_STRATEGY
);
530 fprintf(stderr
, "VNC: error initializing zlib\n");
534 zstream
->opaque
= vs
;
537 // XXX what to do if tight_compression changed in between?
539 // reserve memory in output buffer
540 buffer_reserve(&vs
->output
, vs
->zlib
.offset
+ 64);
543 zstream
->next_in
= vs
->zlib
.buffer
;
544 zstream
->avail_in
= vs
->zlib
.offset
;
545 zstream
->next_out
= vs
->output
.buffer
+ vs
->output
.offset
;
546 zstream
->avail_out
= vs
->output
.capacity
- vs
->output
.offset
;
547 zstream
->data_type
= Z_BINARY
;
548 previous_out
= zstream
->total_out
;
551 if (deflate(zstream
, Z_SYNC_FLUSH
) != Z_OK
) {
552 fprintf(stderr
, "VNC: error during zlib compression\n");
556 vs
->output
.offset
= vs
->output
.capacity
- zstream
->avail_out
;
557 return zstream
->total_out
- previous_out
;
560 static void send_framebuffer_update_zlib(VncState
*vs
, int x
, int y
, int w
, int h
)
562 int old_offset
, new_offset
, bytes_written
;
564 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_ZLIB
);
566 // remember where we put in the follow-up size
567 old_offset
= vs
->output
.offset
;
568 vnc_write_s32(vs
, 0);
570 // compress the stream
572 send_framebuffer_update_raw(vs
, x
, y
, w
, h
);
573 bytes_written
= vnc_zlib_stop(vs
, 0);
575 if (bytes_written
== -1)
579 new_offset
= vs
->output
.offset
;
580 vs
->output
.offset
= old_offset
;
581 vnc_write_u32(vs
, bytes_written
);
582 vs
->output
.offset
= new_offset
;
585 static void send_framebuffer_update(VncState
*vs
, int x
, int y
, int w
, int h
)
587 switch(vs
->vnc_encoding
) {
588 case VNC_ENCODING_ZLIB
:
589 send_framebuffer_update_zlib(vs
, x
, y
, w
, h
);
591 case VNC_ENCODING_HEXTILE
:
592 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_HEXTILE
);
593 send_framebuffer_update_hextile(vs
, x
, y
, w
, h
);
596 vnc_framebuffer_update(vs
, x
, y
, w
, h
, VNC_ENCODING_RAW
);
597 send_framebuffer_update_raw(vs
, x
, y
, w
, h
);
602 static void vnc_copy(DisplayState
*ds
, int src_x
, int src_y
, int dst_x
, int dst_y
, int w
, int h
)
604 VncState
*vs
= ds
->opaque
;
606 vnc_update_client(vs
);
608 vnc_write_u8(vs
, 0); /* msg id */
610 vnc_write_u16(vs
, 1); /* number of rects */
611 vnc_framebuffer_update(vs
, dst_x
, dst_y
, w
, h
, VNC_ENCODING_COPYRECT
);
612 vnc_write_u16(vs
, src_x
);
613 vnc_write_u16(vs
, src_y
);
617 static int find_dirty_height(VncState
*vs
, int y
, int last_x
, int x
)
621 for (h
= 1; h
< (vs
->serverds
.height
- y
); h
++) {
623 if (!vnc_get_bit(vs
->dirty_row
[y
+ h
], last_x
))
625 for (tmp_x
= last_x
; tmp_x
< x
; tmp_x
++)
626 vnc_clear_bit(vs
->dirty_row
[y
+ h
], tmp_x
);
632 static void vnc_update_client(void *opaque
)
634 VncState
*vs
= opaque
;
636 if (vs
->need_update
&& vs
->csock
!= -1) {
640 uint32_t width_mask
[VNC_DIRTY_WORDS
];
647 vnc_set_bits(width_mask
, (ds_get_width(vs
->ds
) / 16), VNC_DIRTY_WORDS
);
649 /* Walk through the dirty map and eliminate tiles that
650 really aren't dirty */
651 row
= ds_get_data(vs
->ds
);
652 old_row
= vs
->old_data
;
654 for (y
= 0; y
< ds_get_height(vs
->ds
); y
++) {
655 if (vnc_and_bits(vs
->dirty_row
[y
], width_mask
, VNC_DIRTY_WORDS
)) {
661 old_ptr
= (char*)old_row
;
663 for (x
= 0; x
< ds_get_width(vs
->ds
); x
+= 16) {
664 if (memcmp(old_ptr
, ptr
, 16 * ds_get_bytes_per_pixel(vs
->ds
)) == 0) {
665 vnc_clear_bit(vs
->dirty_row
[y
], (x
/ 16));
668 memcpy(old_ptr
, ptr
, 16 * ds_get_bytes_per_pixel(vs
->ds
));
671 ptr
+= 16 * ds_get_bytes_per_pixel(vs
->ds
);
672 old_ptr
+= 16 * ds_get_bytes_per_pixel(vs
->ds
);
676 row
+= ds_get_linesize(vs
->ds
);
677 old_row
+= ds_get_linesize(vs
->ds
);
680 if (!has_dirty
&& !vs
->audio_cap
) {
681 qemu_mod_timer(vs
->timer
, qemu_get_clock(rt_clock
) + VNC_REFRESH_INTERVAL
);
685 /* Count rectangles */
687 vnc_write_u8(vs
, 0); /* msg id */
689 saved_offset
= vs
->output
.offset
;
690 vnc_write_u16(vs
, 0);
692 for (y
= 0; y
< vs
->serverds
.height
; y
++) {
695 for (x
= 0; x
< vs
->serverds
.width
/ 16; x
++) {
696 if (vnc_get_bit(vs
->dirty_row
[y
], x
)) {
700 vnc_clear_bit(vs
->dirty_row
[y
], x
);
703 int h
= find_dirty_height(vs
, y
, last_x
, x
);
704 send_framebuffer_update(vs
, last_x
* 16, y
, (x
- last_x
) * 16, h
);
711 int h
= find_dirty_height(vs
, y
, last_x
, x
);
712 send_framebuffer_update(vs
, last_x
* 16, y
, (x
- last_x
) * 16, h
);
716 vs
->output
.buffer
[saved_offset
] = (n_rectangles
>> 8) & 0xFF;
717 vs
->output
.buffer
[saved_offset
+ 1] = n_rectangles
& 0xFF;
722 if (vs
->csock
!= -1) {
723 qemu_mod_timer(vs
->timer
, qemu_get_clock(rt_clock
) + VNC_REFRESH_INTERVAL
);
728 static int vnc_listen_poll(void *opaque
)
730 VncState
*vs
= opaque
;
737 static void audio_capture_notify(void *opaque
, audcnotification_e cmd
)
739 VncState
*vs
= opaque
;
742 case AUD_CNOTIFY_DISABLE
:
743 vnc_write_u8(vs
, 255);
745 vnc_write_u16(vs
, 0);
749 case AUD_CNOTIFY_ENABLE
:
750 vnc_write_u8(vs
, 255);
752 vnc_write_u16(vs
, 1);
758 static void audio_capture_destroy(void *opaque
)
762 static void audio_capture(void *opaque
, void *buf
, int size
)
764 VncState
*vs
= opaque
;
766 vnc_write_u8(vs
, 255);
768 vnc_write_u16(vs
, 2);
769 vnc_write_u32(vs
, size
);
770 vnc_write(vs
, buf
, size
);
774 static void audio_add(VncState
*vs
)
776 struct audio_capture_ops ops
;
779 term_printf ("audio already running\n");
783 ops
.notify
= audio_capture_notify
;
784 ops
.destroy
= audio_capture_destroy
;
785 ops
.capture
= audio_capture
;
787 vs
->audio_cap
= AUD_add_capture(NULL
, &vs
->as
, &ops
, vs
);
788 if (!vs
->audio_cap
) {
789 term_printf ("Failed to add audio capture\n");
793 static void audio_del(VncState
*vs
)
796 AUD_del_capture(vs
->audio_cap
, vs
);
797 vs
->audio_cap
= NULL
;
801 static int vnc_client_io_error(VncState
*vs
, int ret
, int last_errno
)
803 if (ret
== 0 || ret
== -1) {
805 switch (last_errno
) {
817 VNC_DEBUG("Closing down client sock %d %d\n", ret
, ret
< 0 ? last_errno
: 0);
818 qemu_set_fd_handler2(vs
->csock
, NULL
, NULL
, NULL
, NULL
);
819 closesocket(vs
->csock
);
822 buffer_reset(&vs
->input
);
823 buffer_reset(&vs
->output
);
825 #ifdef CONFIG_VNC_TLS
826 if (vs
->tls_session
) {
827 gnutls_deinit(vs
->tls_session
);
828 vs
->tls_session
= NULL
;
830 vs
->wiremode
= VNC_WIREMODE_CLEAR
;
831 #endif /* CONFIG_VNC_TLS */
838 static void vnc_client_error(VncState
*vs
)
840 vnc_client_io_error(vs
, -1, EINVAL
);
843 static void vnc_client_write(void *opaque
)
846 VncState
*vs
= opaque
;
848 #ifdef CONFIG_VNC_TLS
849 if (vs
->tls_session
) {
850 ret
= gnutls_write(vs
->tls_session
, vs
->output
.buffer
, vs
->output
.offset
);
852 if (ret
== GNUTLS_E_AGAIN
)
859 #endif /* CONFIG_VNC_TLS */
860 ret
= send(vs
->csock
, vs
->output
.buffer
, vs
->output
.offset
, 0);
861 ret
= vnc_client_io_error(vs
, ret
, socket_error());
865 memmove(vs
->output
.buffer
, vs
->output
.buffer
+ ret
, (vs
->output
.offset
- ret
));
866 vs
->output
.offset
-= ret
;
868 if (vs
->output
.offset
== 0) {
869 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
873 static void vnc_read_when(VncState
*vs
, VncReadEvent
*func
, size_t expecting
)
875 vs
->read_handler
= func
;
876 vs
->read_handler_expect
= expecting
;
879 static void vnc_client_read(void *opaque
)
881 VncState
*vs
= opaque
;
884 buffer_reserve(&vs
->input
, 4096);
886 #ifdef CONFIG_VNC_TLS
887 if (vs
->tls_session
) {
888 ret
= gnutls_read(vs
->tls_session
, buffer_end(&vs
->input
), 4096);
890 if (ret
== GNUTLS_E_AGAIN
)
897 #endif /* CONFIG_VNC_TLS */
898 ret
= recv(vs
->csock
, buffer_end(&vs
->input
), 4096, 0);
899 ret
= vnc_client_io_error(vs
, ret
, socket_error());
903 vs
->input
.offset
+= ret
;
905 while (vs
->read_handler
&& vs
->input
.offset
>= vs
->read_handler_expect
) {
906 size_t len
= vs
->read_handler_expect
;
909 ret
= vs
->read_handler(vs
, vs
->input
.buffer
, len
);
914 memmove(vs
->input
.buffer
, vs
->input
.buffer
+ len
, (vs
->input
.offset
- len
));
915 vs
->input
.offset
-= len
;
917 vs
->read_handler_expect
= ret
;
922 static void vnc_write(VncState
*vs
, const void *data
, size_t len
)
924 buffer_reserve(&vs
->output
, len
);
926 if (buffer_empty(&vs
->output
)) {
927 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
930 buffer_append(&vs
->output
, data
, len
);
933 static void vnc_write_s32(VncState
*vs
, int32_t value
)
935 vnc_write_u32(vs
, *(uint32_t *)&value
);
938 static void vnc_write_u32(VncState
*vs
, uint32_t value
)
942 buf
[0] = (value
>> 24) & 0xFF;
943 buf
[1] = (value
>> 16) & 0xFF;
944 buf
[2] = (value
>> 8) & 0xFF;
945 buf
[3] = value
& 0xFF;
947 vnc_write(vs
, buf
, 4);
950 static void vnc_write_u16(VncState
*vs
, uint16_t value
)
954 buf
[0] = (value
>> 8) & 0xFF;
955 buf
[1] = value
& 0xFF;
957 vnc_write(vs
, buf
, 2);
960 static void vnc_write_u8(VncState
*vs
, uint8_t value
)
962 vnc_write(vs
, (char *)&value
, 1);
965 static void vnc_flush(VncState
*vs
)
967 if (vs
->output
.offset
)
968 vnc_client_write(vs
);
971 static uint8_t read_u8(uint8_t *data
, size_t offset
)
976 static uint16_t read_u16(uint8_t *data
, size_t offset
)
978 return ((data
[offset
] & 0xFF) << 8) | (data
[offset
+ 1] & 0xFF);
981 static int32_t read_s32(uint8_t *data
, size_t offset
)
983 return (int32_t)((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
984 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
987 static uint32_t read_u32(uint8_t *data
, size_t offset
)
989 return ((data
[offset
] << 24) | (data
[offset
+ 1] << 16) |
990 (data
[offset
+ 2] << 8) | data
[offset
+ 3]);
993 #ifdef CONFIG_VNC_TLS
994 static ssize_t
vnc_tls_push(gnutls_transport_ptr_t transport
,
997 struct VncState
*vs
= (struct VncState
*)transport
;
1001 ret
= send(vs
->csock
, data
, len
, 0);
1011 static ssize_t
vnc_tls_pull(gnutls_transport_ptr_t transport
,
1014 struct VncState
*vs
= (struct VncState
*)transport
;
1018 ret
= recv(vs
->csock
, data
, len
, 0);
1026 #endif /* CONFIG_VNC_TLS */
1028 static void client_cut_text(VncState
*vs
, size_t len
, uint8_t *text
)
1032 static void check_pointer_type_change(VncState
*vs
, int absolute
)
1034 if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
) && vs
->absolute
!= absolute
) {
1035 vnc_write_u8(vs
, 0);
1036 vnc_write_u8(vs
, 0);
1037 vnc_write_u16(vs
, 1);
1038 vnc_framebuffer_update(vs
, absolute
, 0,
1039 ds_get_width(vs
->ds
), ds_get_height(vs
->ds
),
1040 VNC_ENCODING_POINTER_TYPE_CHANGE
);
1043 vs
->absolute
= absolute
;
1046 static void pointer_event(VncState
*vs
, int button_mask
, int x
, int y
)
1051 if (button_mask
& 0x01)
1052 buttons
|= MOUSE_EVENT_LBUTTON
;
1053 if (button_mask
& 0x02)
1054 buttons
|= MOUSE_EVENT_MBUTTON
;
1055 if (button_mask
& 0x04)
1056 buttons
|= MOUSE_EVENT_RBUTTON
;
1057 if (button_mask
& 0x08)
1059 if (button_mask
& 0x10)
1063 kbd_mouse_event(x
* 0x7FFF / (ds_get_width(vs
->ds
) - 1),
1064 y
* 0x7FFF / (ds_get_height(vs
->ds
) - 1),
1066 } else if (vnc_has_feature(vs
, VNC_FEATURE_POINTER_TYPE_CHANGE
)) {
1070 kbd_mouse_event(x
, y
, dz
, buttons
);
1072 if (vs
->last_x
!= -1)
1073 kbd_mouse_event(x
- vs
->last_x
,
1080 check_pointer_type_change(vs
, kbd_mouse_is_absolute());
1083 static void reset_keys(VncState
*vs
)
1086 for(i
= 0; i
< 256; i
++) {
1087 if (vs
->modifiers_state
[i
]) {
1089 kbd_put_keycode(0xe0);
1090 kbd_put_keycode(i
| 0x80);
1091 vs
->modifiers_state
[i
] = 0;
1096 static void press_key(VncState
*vs
, int keysym
)
1098 kbd_put_keycode(keysym2scancode(vs
->kbd_layout
, keysym
) & 0x7f);
1099 kbd_put_keycode(keysym2scancode(vs
->kbd_layout
, keysym
) | 0x80);
1102 static void do_key_event(VncState
*vs
, int down
, int keycode
, int sym
)
1104 /* QEMU console switch */
1106 case 0x2a: /* Left Shift */
1107 case 0x36: /* Right Shift */
1108 case 0x1d: /* Left CTRL */
1109 case 0x9d: /* Right CTRL */
1110 case 0x38: /* Left ALT */
1111 case 0xb8: /* Right ALT */
1113 vs
->modifiers_state
[keycode
] = 1;
1115 vs
->modifiers_state
[keycode
] = 0;
1117 case 0x02 ... 0x0a: /* '1' to '9' keys */
1118 if (down
&& vs
->modifiers_state
[0x1d] && vs
->modifiers_state
[0x38]) {
1119 /* Reset the modifiers sent to the current console */
1121 console_select(keycode
- 0x02);
1125 case 0x3a: /* CapsLock */
1126 case 0x45: /* NumLock */
1128 vs
->modifiers_state
[keycode
] ^= 1;
1132 if (keycode_is_keypad(vs
->kbd_layout
, keycode
)) {
1133 /* If the numlock state needs to change then simulate an additional
1134 keypress before sending this one. This will happen if the user
1135 toggles numlock away from the VNC window.
1137 if (keysym_is_numlock(vs
->kbd_layout
, sym
& 0xFFFF)) {
1138 if (!vs
->modifiers_state
[0x45]) {
1139 vs
->modifiers_state
[0x45] = 1;
1140 press_key(vs
, 0xff7f);
1143 if (vs
->modifiers_state
[0x45]) {
1144 vs
->modifiers_state
[0x45] = 0;
1145 press_key(vs
, 0xff7f);
1150 if (is_graphic_console()) {
1152 kbd_put_keycode(0xe0);
1154 kbd_put_keycode(keycode
& 0x7f);
1156 kbd_put_keycode(keycode
| 0x80);
1158 /* QEMU console emulation */
1161 case 0x2a: /* Left Shift */
1162 case 0x36: /* Right Shift */
1163 case 0x1d: /* Left CTRL */
1164 case 0x9d: /* Right CTRL */
1165 case 0x38: /* Left ALT */
1166 case 0xb8: /* Right ALT */
1169 kbd_put_keysym(QEMU_KEY_UP
);
1172 kbd_put_keysym(QEMU_KEY_DOWN
);
1175 kbd_put_keysym(QEMU_KEY_LEFT
);
1178 kbd_put_keysym(QEMU_KEY_RIGHT
);
1181 kbd_put_keysym(QEMU_KEY_DELETE
);
1184 kbd_put_keysym(QEMU_KEY_HOME
);
1187 kbd_put_keysym(QEMU_KEY_END
);
1190 kbd_put_keysym(QEMU_KEY_PAGEUP
);
1193 kbd_put_keysym(QEMU_KEY_PAGEDOWN
);
1196 kbd_put_keysym(sym
);
1203 static void key_event(VncState
*vs
, int down
, uint32_t sym
)
1207 if (sym
>= 'A' && sym
<= 'Z' && is_graphic_console())
1208 sym
= sym
- 'A' + 'a';
1210 keycode
= keysym2scancode(vs
->kbd_layout
, sym
& 0xFFFF);
1211 do_key_event(vs
, down
, keycode
, sym
);
1214 static void ext_key_event(VncState
*vs
, int down
,
1215 uint32_t sym
, uint16_t keycode
)
1217 /* if the user specifies a keyboard layout, always use it */
1218 if (keyboard_layout
)
1219 key_event(vs
, down
, sym
);
1221 do_key_event(vs
, down
, keycode
, sym
);
1224 static void framebuffer_update_request(VncState
*vs
, int incremental
,
1225 int x_position
, int y_position
,
1228 if (x_position
> ds_get_width(vs
->ds
))
1229 x_position
= ds_get_width(vs
->ds
);
1230 if (y_position
> ds_get_height(vs
->ds
))
1231 y_position
= ds_get_height(vs
->ds
);
1232 if (x_position
+ w
>= ds_get_width(vs
->ds
))
1233 w
= ds_get_width(vs
->ds
) - x_position
;
1234 if (y_position
+ h
>= ds_get_height(vs
->ds
))
1235 h
= ds_get_height(vs
->ds
) - y_position
;
1238 vs
->need_update
= 1;
1240 char *old_row
= vs
->old_data
+ y_position
* ds_get_linesize(vs
->ds
);
1242 for (i
= 0; i
< h
; i
++) {
1243 vnc_set_bits(vs
->dirty_row
[y_position
+ i
],
1244 (ds_get_width(vs
->ds
) / 16), VNC_DIRTY_WORDS
);
1245 memset(old_row
, 42, ds_get_width(vs
->ds
) * ds_get_bytes_per_pixel(vs
->ds
));
1246 old_row
+= ds_get_linesize(vs
->ds
);
1251 static void send_ext_key_event_ack(VncState
*vs
)
1253 vnc_write_u8(vs
, 0);
1254 vnc_write_u8(vs
, 0);
1255 vnc_write_u16(vs
, 1);
1256 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
), ds_get_height(vs
->ds
),
1257 VNC_ENCODING_EXT_KEY_EVENT
);
1261 static void send_ext_audio_ack(VncState
*vs
)
1263 vnc_write_u8(vs
, 0);
1264 vnc_write_u8(vs
, 0);
1265 vnc_write_u16(vs
, 1);
1266 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(vs
->ds
), ds_get_height(vs
->ds
),
1267 VNC_ENCODING_AUDIO
);
1271 static void set_encodings(VncState
*vs
, int32_t *encodings
, size_t n_encodings
)
1274 unsigned int enc
= 0;
1278 vs
->vnc_encoding
= 0;
1279 vs
->tight_compression
= 9;
1280 vs
->tight_quality
= 9;
1282 dcl
->dpy_copy
= NULL
;
1284 for (i
= n_encodings
- 1; i
>= 0; i
--) {
1287 case VNC_ENCODING_RAW
:
1288 vs
->vnc_encoding
= enc
;
1290 case VNC_ENCODING_COPYRECT
:
1291 dcl
->dpy_copy
= vnc_copy
;
1293 case VNC_ENCODING_HEXTILE
:
1294 vs
->features
|= VNC_FEATURE_HEXTILE_MASK
;
1295 vs
->vnc_encoding
= enc
;
1297 case VNC_ENCODING_ZLIB
:
1298 vs
->features
|= VNC_FEATURE_ZLIB_MASK
;
1299 vs
->vnc_encoding
= enc
;
1301 case VNC_ENCODING_DESKTOPRESIZE
:
1302 vs
->features
|= VNC_FEATURE_RESIZE_MASK
;
1304 case VNC_ENCODING_POINTER_TYPE_CHANGE
:
1305 vs
->features
|= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK
;
1307 case VNC_ENCODING_EXT_KEY_EVENT
:
1308 send_ext_key_event_ack(vs
);
1310 case VNC_ENCODING_AUDIO
:
1311 send_ext_audio_ack(vs
);
1313 case VNC_ENCODING_WMVi
:
1314 vs
->features
|= VNC_FEATURE_WMVI_MASK
;
1316 case VNC_ENCODING_COMPRESSLEVEL0
... VNC_ENCODING_COMPRESSLEVEL0
+ 9:
1317 vs
->tight_compression
= (enc
& 0x0F);
1319 case VNC_ENCODING_QUALITYLEVEL0
... VNC_ENCODING_QUALITYLEVEL0
+ 9:
1320 vs
->tight_quality
= (enc
& 0x0F);
1323 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i
, enc
, enc
);
1328 check_pointer_type_change(vs
, kbd_mouse_is_absolute());
1331 static void set_pixel_conversion(VncState
*vs
)
1333 if ((vs
->clientds
.flags
& QEMU_BIG_ENDIAN_FLAG
) ==
1334 (vs
->ds
->surface
->flags
& QEMU_BIG_ENDIAN_FLAG
) &&
1335 !memcmp(&(vs
->clientds
.pf
), &(vs
->ds
->surface
->pf
), sizeof(PixelFormat
))) {
1336 vs
->write_pixels
= vnc_write_pixels_copy
;
1337 switch (vs
->ds
->surface
->pf
.bits_per_pixel
) {
1339 vs
->send_hextile_tile
= send_hextile_tile_8
;
1342 vs
->send_hextile_tile
= send_hextile_tile_16
;
1345 vs
->send_hextile_tile
= send_hextile_tile_32
;
1349 vs
->write_pixels
= vnc_write_pixels_generic
;
1350 switch (vs
->ds
->surface
->pf
.bits_per_pixel
) {
1352 vs
->send_hextile_tile
= send_hextile_tile_generic_8
;
1355 vs
->send_hextile_tile
= send_hextile_tile_generic_16
;
1358 vs
->send_hextile_tile
= send_hextile_tile_generic_32
;
1364 static void set_pixel_format(VncState
*vs
,
1365 int bits_per_pixel
, int depth
,
1366 int big_endian_flag
, int true_color_flag
,
1367 int red_max
, int green_max
, int blue_max
,
1368 int red_shift
, int green_shift
, int blue_shift
)
1370 if (!true_color_flag
) {
1371 vnc_client_error(vs
);
1375 vs
->clientds
= vs
->serverds
;
1376 vs
->clientds
.pf
.rmax
= red_max
;
1377 count_bits(vs
->clientds
.pf
.rbits
, red_max
);
1378 vs
->clientds
.pf
.rshift
= red_shift
;
1379 vs
->clientds
.pf
.rmask
= red_max
<< red_shift
;
1380 vs
->clientds
.pf
.gmax
= green_max
;
1381 count_bits(vs
->clientds
.pf
.gbits
, green_max
);
1382 vs
->clientds
.pf
.gshift
= green_shift
;
1383 vs
->clientds
.pf
.gmask
= green_max
<< green_shift
;
1384 vs
->clientds
.pf
.bmax
= blue_max
;
1385 count_bits(vs
->clientds
.pf
.bbits
, blue_max
);
1386 vs
->clientds
.pf
.bshift
= blue_shift
;
1387 vs
->clientds
.pf
.bmask
= blue_max
<< blue_shift
;
1388 vs
->clientds
.pf
.bits_per_pixel
= bits_per_pixel
;
1389 vs
->clientds
.pf
.bytes_per_pixel
= bits_per_pixel
/ 8;
1390 vs
->clientds
.pf
.depth
= bits_per_pixel
== 32 ? 24 : bits_per_pixel
;
1391 vs
->clientds
.flags
= big_endian_flag
? QEMU_BIG_ENDIAN_FLAG
: 0x00;
1393 set_pixel_conversion(vs
);
1395 vga_hw_invalidate();
1399 static void pixel_format_message (VncState
*vs
) {
1400 char pad
[3] = { 0, 0, 0 };
1402 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.bits_per_pixel
); /* bits-per-pixel */
1403 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.depth
); /* depth */
1405 #ifdef WORDS_BIGENDIAN
1406 vnc_write_u8(vs
, 1); /* big-endian-flag */
1408 vnc_write_u8(vs
, 0); /* big-endian-flag */
1410 vnc_write_u8(vs
, 1); /* true-color-flag */
1411 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.rmax
); /* red-max */
1412 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.gmax
); /* green-max */
1413 vnc_write_u16(vs
, vs
->ds
->surface
->pf
.bmax
); /* blue-max */
1414 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.rshift
); /* red-shift */
1415 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.gshift
); /* green-shift */
1416 vnc_write_u8(vs
, vs
->ds
->surface
->pf
.bshift
); /* blue-shift */
1417 if (vs
->ds
->surface
->pf
.bits_per_pixel
== 32)
1418 vs
->send_hextile_tile
= send_hextile_tile_32
;
1419 else if (vs
->ds
->surface
->pf
.bits_per_pixel
== 16)
1420 vs
->send_hextile_tile
= send_hextile_tile_16
;
1421 else if (vs
->ds
->surface
->pf
.bits_per_pixel
== 8)
1422 vs
->send_hextile_tile
= send_hextile_tile_8
;
1423 vs
->clientds
= *(vs
->ds
->surface
);
1424 vs
->clientds
.flags
|= ~QEMU_ALLOCATED_FLAG
;
1425 vs
->write_pixels
= vnc_write_pixels_copy
;
1427 vnc_write(vs
, pad
, 3); /* padding */
1430 static void vnc_dpy_setdata(DisplayState
*ds
)
1432 /* We don't have to do anything */
1435 static void vnc_colordepth(DisplayState
*ds
)
1437 struct VncState
*vs
= ds
->opaque
;
1439 if (vs
->csock
!= -1 && vnc_has_feature(vs
, VNC_FEATURE_WMVI
)) {
1440 /* Sending a WMVi message to notify the client*/
1441 vnc_write_u8(vs
, 0); /* msg id */
1442 vnc_write_u8(vs
, 0);
1443 vnc_write_u16(vs
, 1); /* number of rects */
1444 vnc_framebuffer_update(vs
, 0, 0, ds_get_width(ds
), ds_get_height(ds
),
1446 pixel_format_message(vs
);
1449 set_pixel_conversion(vs
);
1453 static int protocol_client_msg(VncState
*vs
, uint8_t *data
, size_t len
)
1463 set_pixel_format(vs
, read_u8(data
, 4), read_u8(data
, 5),
1464 read_u8(data
, 6), read_u8(data
, 7),
1465 read_u16(data
, 8), read_u16(data
, 10),
1466 read_u16(data
, 12), read_u8(data
, 14),
1467 read_u8(data
, 15), read_u8(data
, 16));
1474 limit
= read_u16(data
, 2);
1476 return 4 + (limit
* 4);
1478 limit
= read_u16(data
, 2);
1480 for (i
= 0; i
< limit
; i
++) {
1481 int32_t val
= read_s32(data
, 4 + (i
* 4));
1482 memcpy(data
+ 4 + (i
* 4), &val
, sizeof(val
));
1485 set_encodings(vs
, (int32_t *)(data
+ 4), limit
);
1491 framebuffer_update_request(vs
,
1492 read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4),
1493 read_u16(data
, 6), read_u16(data
, 8));
1499 key_event(vs
, read_u8(data
, 1), read_u32(data
, 4));
1505 pointer_event(vs
, read_u8(data
, 1), read_u16(data
, 2), read_u16(data
, 4));
1512 uint32_t dlen
= read_u32(data
, 4);
1517 client_cut_text(vs
, read_u32(data
, 4), data
+ 8);
1523 switch (read_u8(data
, 1)) {
1528 ext_key_event(vs
, read_u16(data
, 2),
1529 read_u32(data
, 4), read_u32(data
, 8));
1535 switch (read_u16 (data
, 2)) {
1545 switch (read_u8(data
, 4)) {
1546 case 0: vs
->as
.fmt
= AUD_FMT_U8
; break;
1547 case 1: vs
->as
.fmt
= AUD_FMT_S8
; break;
1548 case 2: vs
->as
.fmt
= AUD_FMT_U16
; break;
1549 case 3: vs
->as
.fmt
= AUD_FMT_S16
; break;
1550 case 4: vs
->as
.fmt
= AUD_FMT_U32
; break;
1551 case 5: vs
->as
.fmt
= AUD_FMT_S32
; break;
1553 printf("Invalid audio format %d\n", read_u8(data
, 4));
1554 vnc_client_error(vs
);
1557 vs
->as
.nchannels
= read_u8(data
, 5);
1558 if (vs
->as
.nchannels
!= 1 && vs
->as
.nchannels
!= 2) {
1559 printf("Invalid audio channel coount %d\n",
1561 vnc_client_error(vs
);
1564 vs
->as
.freq
= read_u32(data
, 6);
1567 printf ("Invalid audio message %d\n", read_u8(data
, 4));
1568 vnc_client_error(vs
);
1574 printf("Msg: %d\n", read_u16(data
, 0));
1575 vnc_client_error(vs
);
1580 printf("Msg: %d\n", data
[0]);
1581 vnc_client_error(vs
);
1585 vnc_read_when(vs
, protocol_client_msg
, 1);
1589 static int protocol_client_init(VncState
*vs
, uint8_t *data
, size_t len
)
1594 vnc_write_u16(vs
, ds_get_width(vs
->ds
));
1595 vnc_write_u16(vs
, ds_get_height(vs
->ds
));
1597 pixel_format_message(vs
);
1600 size
= snprintf(buf
, sizeof(buf
), "QEMU (%s)", qemu_name
);
1602 size
= snprintf(buf
, sizeof(buf
), "QEMU");
1604 vnc_write_u32(vs
, size
);
1605 vnc_write(vs
, buf
, size
);
1608 vnc_read_when(vs
, protocol_client_msg
, 1);
1613 static void make_challenge(VncState
*vs
)
1617 srand(time(NULL
)+getpid()+getpid()*987654+rand());
1619 for (i
= 0 ; i
< sizeof(vs
->challenge
) ; i
++)
1620 vs
->challenge
[i
] = (int) (256.0*rand()/(RAND_MAX
+1.0));
1623 static int protocol_client_auth_vnc(VncState
*vs
, uint8_t *data
, size_t len
)
1625 unsigned char response
[VNC_AUTH_CHALLENGE_SIZE
];
1627 unsigned char key
[8];
1629 if (!vs
->password
|| !vs
->password
[0]) {
1630 VNC_DEBUG("No password configured on server");
1631 vnc_write_u32(vs
, 1); /* Reject auth */
1632 if (vs
->minor
>= 8) {
1633 static const char err
[] = "Authentication failed";
1634 vnc_write_u32(vs
, sizeof(err
));
1635 vnc_write(vs
, err
, sizeof(err
));
1638 vnc_client_error(vs
);
1642 memcpy(response
, vs
->challenge
, VNC_AUTH_CHALLENGE_SIZE
);
1644 /* Calculate the expected challenge response */
1645 pwlen
= strlen(vs
->password
);
1646 for (i
=0; i
<sizeof(key
); i
++)
1647 key
[i
] = i
<pwlen
? vs
->password
[i
] : 0;
1649 for (j
= 0; j
< VNC_AUTH_CHALLENGE_SIZE
; j
+= 8)
1650 des(response
+j
, response
+j
);
1652 /* Compare expected vs actual challenge response */
1653 if (memcmp(response
, data
, VNC_AUTH_CHALLENGE_SIZE
) != 0) {
1654 VNC_DEBUG("Client challenge reponse did not match\n");
1655 vnc_write_u32(vs
, 1); /* Reject auth */
1656 if (vs
->minor
>= 8) {
1657 static const char err
[] = "Authentication failed";
1658 vnc_write_u32(vs
, sizeof(err
));
1659 vnc_write(vs
, err
, sizeof(err
));
1662 vnc_client_error(vs
);
1664 VNC_DEBUG("Accepting VNC challenge response\n");
1665 vnc_write_u32(vs
, 0); /* Accept auth */
1668 vnc_read_when(vs
, protocol_client_init
, 1);
1673 static int start_auth_vnc(VncState
*vs
)
1676 /* Send client a 'random' challenge */
1677 vnc_write(vs
, vs
->challenge
, sizeof(vs
->challenge
));
1680 vnc_read_when(vs
, protocol_client_auth_vnc
, sizeof(vs
->challenge
));
1685 #ifdef CONFIG_VNC_TLS
1686 #define DH_BITS 1024
1687 static gnutls_dh_params_t dh_params
;
1689 static int vnc_tls_initialize(void)
1691 static int tlsinitialized
= 0;
1696 if (gnutls_global_init () < 0)
1699 /* XXX ought to re-generate diffie-hellmen params periodically */
1700 if (gnutls_dh_params_init (&dh_params
) < 0)
1702 if (gnutls_dh_params_generate2 (dh_params
, DH_BITS
) < 0)
1705 #if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
1706 gnutls_global_set_log_level(10);
1707 gnutls_global_set_log_function(vnc_debug_gnutls_log
);
1715 static gnutls_anon_server_credentials
vnc_tls_initialize_anon_cred(void)
1717 gnutls_anon_server_credentials anon_cred
;
1720 if ((ret
= gnutls_anon_allocate_server_credentials(&anon_cred
)) < 0) {
1721 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1725 gnutls_anon_set_server_dh_params(anon_cred
, dh_params
);
1731 static gnutls_certificate_credentials_t
vnc_tls_initialize_x509_cred(VncState
*vs
)
1733 gnutls_certificate_credentials_t x509_cred
;
1736 if (!vs
->x509cacert
) {
1737 VNC_DEBUG("No CA x509 certificate specified\n");
1740 if (!vs
->x509cert
) {
1741 VNC_DEBUG("No server x509 certificate specified\n");
1745 VNC_DEBUG("No server private key specified\n");
1749 if ((ret
= gnutls_certificate_allocate_credentials(&x509_cred
)) < 0) {
1750 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret
));
1753 if ((ret
= gnutls_certificate_set_x509_trust_file(x509_cred
,
1755 GNUTLS_X509_FMT_PEM
)) < 0) {
1756 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret
));
1757 gnutls_certificate_free_credentials(x509_cred
);
1761 if ((ret
= gnutls_certificate_set_x509_key_file (x509_cred
,
1764 GNUTLS_X509_FMT_PEM
)) < 0) {
1765 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret
));
1766 gnutls_certificate_free_credentials(x509_cred
);
1770 if (vs
->x509cacrl
) {
1771 if ((ret
= gnutls_certificate_set_x509_crl_file(x509_cred
,
1773 GNUTLS_X509_FMT_PEM
)) < 0) {
1774 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret
));
1775 gnutls_certificate_free_credentials(x509_cred
);
1780 gnutls_certificate_set_dh_params (x509_cred
, dh_params
);
1785 static int vnc_validate_certificate(struct VncState
*vs
)
1788 unsigned int status
;
1789 const gnutls_datum_t
*certs
;
1790 unsigned int nCerts
, i
;
1793 VNC_DEBUG("Validating client certificate\n");
1794 if ((ret
= gnutls_certificate_verify_peers2 (vs
->tls_session
, &status
)) < 0) {
1795 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret
));
1799 if ((now
= time(NULL
)) == ((time_t)-1)) {
1804 if (status
& GNUTLS_CERT_INVALID
)
1805 VNC_DEBUG("The certificate is not trusted.\n");
1807 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
1808 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1810 if (status
& GNUTLS_CERT_REVOKED
)
1811 VNC_DEBUG("The certificate has been revoked.\n");
1813 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
1814 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1818 VNC_DEBUG("Certificate is valid!\n");
1821 /* Only support x509 for now */
1822 if (gnutls_certificate_type_get(vs
->tls_session
) != GNUTLS_CRT_X509
)
1825 if (!(certs
= gnutls_certificate_get_peers(vs
->tls_session
, &nCerts
)))
1828 for (i
= 0 ; i
< nCerts
; i
++) {
1829 gnutls_x509_crt_t cert
;
1830 VNC_DEBUG ("Checking certificate chain %d\n", i
);
1831 if (gnutls_x509_crt_init (&cert
) < 0)
1834 if (gnutls_x509_crt_import(cert
, &certs
[i
], GNUTLS_X509_FMT_DER
) < 0) {
1835 gnutls_x509_crt_deinit (cert
);
1839 if (gnutls_x509_crt_get_expiration_time (cert
) < now
) {
1840 VNC_DEBUG("The certificate has expired\n");
1841 gnutls_x509_crt_deinit (cert
);
1845 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1846 VNC_DEBUG("The certificate is not yet activated\n");
1847 gnutls_x509_crt_deinit (cert
);
1851 if (gnutls_x509_crt_get_activation_time (cert
) > now
) {
1852 VNC_DEBUG("The certificate is not yet activated\n");
1853 gnutls_x509_crt_deinit (cert
);
1857 gnutls_x509_crt_deinit (cert
);
1864 static int start_auth_vencrypt_subauth(VncState
*vs
)
1866 switch (vs
->subauth
) {
1867 case VNC_AUTH_VENCRYPT_TLSNONE
:
1868 case VNC_AUTH_VENCRYPT_X509NONE
:
1869 VNC_DEBUG("Accept TLS auth none\n");
1870 vnc_write_u32(vs
, 0); /* Accept auth completion */
1871 vnc_read_when(vs
, protocol_client_init
, 1);
1874 case VNC_AUTH_VENCRYPT_TLSVNC
:
1875 case VNC_AUTH_VENCRYPT_X509VNC
:
1876 VNC_DEBUG("Start TLS auth VNC\n");
1877 return start_auth_vnc(vs
);
1879 default: /* Should not be possible, but just in case */
1880 VNC_DEBUG("Reject auth %d\n", vs
->auth
);
1881 vnc_write_u8(vs
, 1);
1882 if (vs
->minor
>= 8) {
1883 static const char err
[] = "Unsupported authentication type";
1884 vnc_write_u32(vs
, sizeof(err
));
1885 vnc_write(vs
, err
, sizeof(err
));
1887 vnc_client_error(vs
);
1893 static void vnc_handshake_io(void *opaque
);
1895 static int vnc_continue_handshake(struct VncState
*vs
) {
1898 if ((ret
= gnutls_handshake(vs
->tls_session
)) < 0) {
1899 if (!gnutls_error_is_fatal(ret
)) {
1900 VNC_DEBUG("Handshake interrupted (blocking)\n");
1901 if (!gnutls_record_get_direction(vs
->tls_session
))
1902 qemu_set_fd_handler(vs
->csock
, vnc_handshake_io
, NULL
, vs
);
1904 qemu_set_fd_handler(vs
->csock
, NULL
, vnc_handshake_io
, vs
);
1907 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret
));
1908 vnc_client_error(vs
);
1912 if (vs
->x509verify
) {
1913 if (vnc_validate_certificate(vs
) < 0) {
1914 VNC_DEBUG("Client verification failed\n");
1915 vnc_client_error(vs
);
1918 VNC_DEBUG("Client verification passed\n");
1922 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1923 vs
->wiremode
= VNC_WIREMODE_TLS
;
1924 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, vnc_client_write
, vs
);
1926 return start_auth_vencrypt_subauth(vs
);
1929 static void vnc_handshake_io(void *opaque
) {
1930 struct VncState
*vs
= (struct VncState
*)opaque
;
1932 VNC_DEBUG("Handshake IO continue\n");
1933 vnc_continue_handshake(vs
);
1936 #define NEED_X509_AUTH(vs) \
1937 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1938 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1939 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1942 static int vnc_start_tls(struct VncState
*vs
) {
1943 static const int cert_type_priority
[] = { GNUTLS_CRT_X509
, 0 };
1944 static const int protocol_priority
[]= { GNUTLS_TLS1_1
, GNUTLS_TLS1_0
, GNUTLS_SSL3
, 0 };
1945 static const int kx_anon
[] = {GNUTLS_KX_ANON_DH
, 0};
1946 static const int kx_x509
[] = {GNUTLS_KX_DHE_DSS
, GNUTLS_KX_RSA
, GNUTLS_KX_DHE_RSA
, GNUTLS_KX_SRP
, 0};
1948 VNC_DEBUG("Do TLS setup\n");
1949 if (vnc_tls_initialize() < 0) {
1950 VNC_DEBUG("Failed to init TLS\n");
1951 vnc_client_error(vs
);
1954 if (vs
->tls_session
== NULL
) {
1955 if (gnutls_init(&vs
->tls_session
, GNUTLS_SERVER
) < 0) {
1956 vnc_client_error(vs
);
1960 if (gnutls_set_default_priority(vs
->tls_session
) < 0) {
1961 gnutls_deinit(vs
->tls_session
);
1962 vs
->tls_session
= NULL
;
1963 vnc_client_error(vs
);
1967 if (gnutls_kx_set_priority(vs
->tls_session
, NEED_X509_AUTH(vs
) ? kx_x509
: kx_anon
) < 0) {
1968 gnutls_deinit(vs
->tls_session
);
1969 vs
->tls_session
= NULL
;
1970 vnc_client_error(vs
);
1974 if (gnutls_certificate_type_set_priority(vs
->tls_session
, cert_type_priority
) < 0) {
1975 gnutls_deinit(vs
->tls_session
);
1976 vs
->tls_session
= NULL
;
1977 vnc_client_error(vs
);
1981 if (gnutls_protocol_set_priority(vs
->tls_session
, protocol_priority
) < 0) {
1982 gnutls_deinit(vs
->tls_session
);
1983 vs
->tls_session
= NULL
;
1984 vnc_client_error(vs
);
1988 if (NEED_X509_AUTH(vs
)) {
1989 gnutls_certificate_server_credentials x509_cred
= vnc_tls_initialize_x509_cred(vs
);
1991 gnutls_deinit(vs
->tls_session
);
1992 vs
->tls_session
= NULL
;
1993 vnc_client_error(vs
);
1996 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_CERTIFICATE
, x509_cred
) < 0) {
1997 gnutls_deinit(vs
->tls_session
);
1998 vs
->tls_session
= NULL
;
1999 gnutls_certificate_free_credentials(x509_cred
);
2000 vnc_client_error(vs
);
2003 if (vs
->x509verify
) {
2004 VNC_DEBUG("Requesting a client certificate\n");
2005 gnutls_certificate_server_set_request (vs
->tls_session
, GNUTLS_CERT_REQUEST
);
2009 gnutls_anon_server_credentials anon_cred
= vnc_tls_initialize_anon_cred();
2011 gnutls_deinit(vs
->tls_session
);
2012 vs
->tls_session
= NULL
;
2013 vnc_client_error(vs
);
2016 if (gnutls_credentials_set(vs
->tls_session
, GNUTLS_CRD_ANON
, anon_cred
) < 0) {
2017 gnutls_deinit(vs
->tls_session
);
2018 vs
->tls_session
= NULL
;
2019 gnutls_anon_free_server_credentials(anon_cred
);
2020 vnc_client_error(vs
);
2025 gnutls_transport_set_ptr(vs
->tls_session
, (gnutls_transport_ptr_t
)vs
);
2026 gnutls_transport_set_push_function(vs
->tls_session
, vnc_tls_push
);
2027 gnutls_transport_set_pull_function(vs
->tls_session
, vnc_tls_pull
);
2030 VNC_DEBUG("Start TLS handshake process\n");
2031 return vnc_continue_handshake(vs
);
2034 static int protocol_client_vencrypt_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2036 int auth
= read_u32(data
, 0);
2038 if (auth
!= vs
->subauth
) {
2039 VNC_DEBUG("Rejecting auth %d\n", auth
);
2040 vnc_write_u8(vs
, 0); /* Reject auth */
2042 vnc_client_error(vs
);
2044 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth
);
2045 vnc_write_u8(vs
, 1); /* Accept auth */
2048 if (vnc_start_tls(vs
) < 0) {
2049 VNC_DEBUG("Failed to complete TLS\n");
2053 if (vs
->wiremode
== VNC_WIREMODE_TLS
) {
2054 VNC_DEBUG("Starting VeNCrypt subauth\n");
2055 return start_auth_vencrypt_subauth(vs
);
2057 VNC_DEBUG("TLS handshake blocked\n");
2064 static int protocol_client_vencrypt_init(VncState
*vs
, uint8_t *data
, size_t len
)
2068 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data
[0], (int)data
[1]);
2069 vnc_write_u8(vs
, 1); /* Reject version */
2071 vnc_client_error(vs
);
2073 VNC_DEBUG("Sending allowed auth %d\n", vs
->subauth
);
2074 vnc_write_u8(vs
, 0); /* Accept version */
2075 vnc_write_u8(vs
, 1); /* Number of sub-auths */
2076 vnc_write_u32(vs
, vs
->subauth
); /* The supported auth */
2078 vnc_read_when(vs
, protocol_client_vencrypt_auth
, 4);
2083 static int start_auth_vencrypt(VncState
*vs
)
2085 /* Send VeNCrypt version 0.2 */
2086 vnc_write_u8(vs
, 0);
2087 vnc_write_u8(vs
, 2);
2089 vnc_read_when(vs
, protocol_client_vencrypt_init
, 2);
2092 #endif /* CONFIG_VNC_TLS */
2094 static int protocol_client_auth(VncState
*vs
, uint8_t *data
, size_t len
)
2096 /* We only advertise 1 auth scheme at a time, so client
2097 * must pick the one we sent. Verify this */
2098 if (data
[0] != vs
->auth
) { /* Reject auth */
2099 VNC_DEBUG("Reject auth %d\n", (int)data
[0]);
2100 vnc_write_u32(vs
, 1);
2101 if (vs
->minor
>= 8) {
2102 static const char err
[] = "Authentication failed";
2103 vnc_write_u32(vs
, sizeof(err
));
2104 vnc_write(vs
, err
, sizeof(err
));
2106 vnc_client_error(vs
);
2107 } else { /* Accept requested auth */
2108 VNC_DEBUG("Client requested auth %d\n", (int)data
[0]);
2111 VNC_DEBUG("Accept auth none\n");
2112 if (vs
->minor
>= 8) {
2113 vnc_write_u32(vs
, 0); /* Accept auth completion */
2116 vnc_read_when(vs
, protocol_client_init
, 1);
2120 VNC_DEBUG("Start VNC auth\n");
2121 return start_auth_vnc(vs
);
2123 #ifdef CONFIG_VNC_TLS
2124 case VNC_AUTH_VENCRYPT
:
2125 VNC_DEBUG("Accept VeNCrypt auth\n");;
2126 return start_auth_vencrypt(vs
);
2127 #endif /* CONFIG_VNC_TLS */
2129 default: /* Should not be possible, but just in case */
2130 VNC_DEBUG("Reject auth %d\n", vs
->auth
);
2131 vnc_write_u8(vs
, 1);
2132 if (vs
->minor
>= 8) {
2133 static const char err
[] = "Authentication failed";
2134 vnc_write_u32(vs
, sizeof(err
));
2135 vnc_write(vs
, err
, sizeof(err
));
2137 vnc_client_error(vs
);
2143 static int protocol_version(VncState
*vs
, uint8_t *version
, size_t len
)
2147 memcpy(local
, version
, 12);
2150 if (sscanf(local
, "RFB %03d.%03d\n", &vs
->major
, &vs
->minor
) != 2) {
2151 VNC_DEBUG("Malformed protocol version %s\n", local
);
2152 vnc_client_error(vs
);
2155 VNC_DEBUG("Client request protocol version %d.%d\n", vs
->major
, vs
->minor
);
2156 if (vs
->major
!= 3 ||
2162 VNC_DEBUG("Unsupported client version\n");
2163 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2165 vnc_client_error(vs
);
2168 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2169 * as equivalent to v3.3 by servers
2171 if (vs
->minor
== 4 || vs
->minor
== 5)
2174 if (vs
->minor
== 3) {
2175 if (vs
->auth
== VNC_AUTH_NONE
) {
2176 VNC_DEBUG("Tell client auth none\n");
2177 vnc_write_u32(vs
, vs
->auth
);
2179 vnc_read_when(vs
, protocol_client_init
, 1);
2180 } else if (vs
->auth
== VNC_AUTH_VNC
) {
2181 VNC_DEBUG("Tell client VNC auth\n");
2182 vnc_write_u32(vs
, vs
->auth
);
2186 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs
->auth
);
2187 vnc_write_u32(vs
, VNC_AUTH_INVALID
);
2189 vnc_client_error(vs
);
2192 VNC_DEBUG("Telling client we support auth %d\n", vs
->auth
);
2193 vnc_write_u8(vs
, 1); /* num auth */
2194 vnc_write_u8(vs
, vs
->auth
);
2195 vnc_read_when(vs
, protocol_client_auth
, 1);
2202 static void vnc_connect(VncState
*vs
)
2204 VNC_DEBUG("New client on socket %d\n", vs
->csock
);
2206 socket_set_nonblock(vs
->csock
);
2207 qemu_set_fd_handler2(vs
->csock
, NULL
, vnc_client_read
, NULL
, vs
);
2208 vnc_write(vs
, "RFB 003.008\n", 12);
2210 vnc_read_when(vs
, protocol_version
, 12);
2211 memset(vs
->old_data
, 0, ds_get_linesize(vs
->ds
) * ds_get_height(vs
->ds
));
2212 memset(vs
->dirty_row
, 0xFF, sizeof(vs
->dirty_row
));
2214 dcl
->dpy_copy
= NULL
;
2215 vnc_update_client(vs
);
2219 static void vnc_listen_read(void *opaque
)
2221 VncState
*vs
= opaque
;
2222 struct sockaddr_in addr
;
2223 socklen_t addrlen
= sizeof(addr
);
2228 vs
->csock
= accept(vs
->lsock
, (struct sockaddr
*)&addr
, &addrlen
);
2229 if (vs
->csock
!= -1) {
2234 void vnc_display_init(DisplayState
*ds
)
2238 vs
= qemu_mallocz(sizeof(VncState
));
2239 dcl
= qemu_mallocz(sizeof(DisplayChangeListener
));
2245 vs
->password
= NULL
;
2254 if (keyboard_layout
)
2255 vs
->kbd_layout
= init_keyboard_layout(keyboard_layout
);
2257 vs
->kbd_layout
= init_keyboard_layout("en-us");
2259 if (!vs
->kbd_layout
)
2262 vs
->timer
= qemu_new_timer(rt_clock
, vnc_update_client
, vs
);
2264 dcl
->dpy_update
= vnc_dpy_update
;
2265 dcl
->dpy_resize
= vnc_dpy_resize
;
2266 dcl
->dpy_setdata
= vnc_dpy_setdata
;
2267 dcl
->dpy_refresh
= NULL
;
2268 register_displaychangelistener(ds
, dcl
);
2270 vs
->as
.freq
= 44100;
2271 vs
->as
.nchannels
= 2;
2272 vs
->as
.fmt
= AUD_FMT_S16
;
2273 vs
->as
.endianness
= 0;
2276 #ifdef CONFIG_VNC_TLS
2277 static int vnc_set_x509_credential(VncState
*vs
,
2278 const char *certdir
,
2279 const char *filename
,
2290 *cred
= qemu_malloc(strlen(certdir
) + strlen(filename
) + 2);
2292 strcpy(*cred
, certdir
);
2294 strcat(*cred
, filename
);
2296 VNC_DEBUG("Check %s\n", *cred
);
2297 if (stat(*cred
, &sb
) < 0) {
2300 if (ignoreMissing
&& errno
== ENOENT
)
2308 static int vnc_set_x509_credential_dir(VncState
*vs
,
2309 const char *certdir
)
2311 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CERT_FILE
, &vs
->x509cacert
, 0) < 0)
2313 if (vnc_set_x509_credential(vs
, certdir
, X509_CA_CRL_FILE
, &vs
->x509cacrl
, 1) < 0)
2315 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_CERT_FILE
, &vs
->x509cert
, 0) < 0)
2317 if (vnc_set_x509_credential(vs
, certdir
, X509_SERVER_KEY_FILE
, &vs
->x509key
, 0) < 0)
2323 qemu_free(vs
->x509cacert
);
2324 qemu_free(vs
->x509cacrl
);
2325 qemu_free(vs
->x509cert
);
2326 qemu_free(vs
->x509key
);
2327 vs
->x509cacert
= vs
->x509cacrl
= vs
->x509cert
= vs
->x509key
= NULL
;
2330 #endif /* CONFIG_VNC_TLS */
2332 void vnc_display_close(DisplayState
*ds
)
2334 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2339 qemu_free(vs
->display
);
2342 if (vs
->lsock
!= -1) {
2343 qemu_set_fd_handler2(vs
->lsock
, NULL
, NULL
, NULL
, NULL
);
2347 if (vs
->csock
!= -1) {
2348 qemu_set_fd_handler2(vs
->csock
, NULL
, NULL
, NULL
, NULL
);
2349 closesocket(vs
->csock
);
2351 buffer_reset(&vs
->input
);
2352 buffer_reset(&vs
->output
);
2353 vs
->need_update
= 0;
2354 #ifdef CONFIG_VNC_TLS
2355 if (vs
->tls_session
) {
2356 gnutls_deinit(vs
->tls_session
);
2357 vs
->tls_session
= NULL
;
2359 vs
->wiremode
= VNC_WIREMODE_CLEAR
;
2360 #endif /* CONFIG_VNC_TLS */
2362 vs
->auth
= VNC_AUTH_INVALID
;
2363 #ifdef CONFIG_VNC_TLS
2364 vs
->subauth
= VNC_AUTH_INVALID
;
2370 int vnc_display_password(DisplayState
*ds
, const char *password
)
2372 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2375 qemu_free(vs
->password
);
2376 vs
->password
= NULL
;
2378 if (password
&& password
[0]) {
2379 if (!(vs
->password
= qemu_strdup(password
)))
2386 int vnc_display_open(DisplayState
*ds
, const char *display
)
2388 VncState
*vs
= ds
? (VncState
*)ds
->opaque
: vnc_state
;
2389 const char *options
;
2393 #ifdef CONFIG_VNC_TLS
2394 int tls
= 0, x509
= 0;
2399 vnc_display_close(ds
);
2400 if (strcmp(display
, "none") == 0)
2403 if (!(vs
->display
= strdup(display
)))
2407 while ((options
= strchr(options
, ','))) {
2409 if (strncmp(options
, "password", 8) == 0) {
2410 password
= 1; /* Require password auth */
2411 } else if (strncmp(options
, "reverse", 7) == 0) {
2413 } else if (strncmp(options
, "to=", 3) == 0) {
2414 to_port
= atoi(options
+3) + 5900;
2415 #ifdef CONFIG_VNC_TLS
2416 } else if (strncmp(options
, "tls", 3) == 0) {
2417 tls
= 1; /* Require TLS */
2418 } else if (strncmp(options
, "x509", 4) == 0) {
2420 x509
= 1; /* Require x509 certificates */
2421 if (strncmp(options
, "x509verify", 10) == 0)
2422 vs
->x509verify
= 1; /* ...and verify client certs */
2424 /* Now check for 'x509=/some/path' postfix
2425 * and use that to setup x509 certificate/key paths */
2426 start
= strchr(options
, '=');
2427 end
= strchr(options
, ',');
2428 if (start
&& (!end
|| (start
< end
))) {
2429 int len
= end
? end
-(start
+1) : strlen(start
+1);
2430 char *path
= qemu_strndup(start
+ 1, len
);
2432 VNC_DEBUG("Trying certificate path '%s'\n", path
);
2433 if (vnc_set_x509_credential_dir(vs
, path
) < 0) {
2434 fprintf(stderr
, "Failed to find x509 certificates/keys in %s\n", path
);
2436 qemu_free(vs
->display
);
2442 fprintf(stderr
, "No certificate path provided\n");
2443 qemu_free(vs
->display
);
2452 #ifdef CONFIG_VNC_TLS
2454 vs
->auth
= VNC_AUTH_VENCRYPT
;
2456 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2457 vs
->subauth
= VNC_AUTH_VENCRYPT_X509VNC
;
2459 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2460 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSVNC
;
2464 VNC_DEBUG("Initializing VNC server with password auth\n");
2465 vs
->auth
= VNC_AUTH_VNC
;
2466 #ifdef CONFIG_VNC_TLS
2467 vs
->subauth
= VNC_AUTH_INVALID
;
2471 #ifdef CONFIG_VNC_TLS
2473 vs
->auth
= VNC_AUTH_VENCRYPT
;
2475 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2476 vs
->subauth
= VNC_AUTH_VENCRYPT_X509NONE
;
2478 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2479 vs
->subauth
= VNC_AUTH_VENCRYPT_TLSNONE
;
2483 VNC_DEBUG("Initializing VNC server with no auth\n");
2484 vs
->auth
= VNC_AUTH_NONE
;
2485 #ifdef CONFIG_VNC_TLS
2486 vs
->subauth
= VNC_AUTH_INVALID
;
2492 /* connect to viewer */
2493 if (strncmp(display
, "unix:", 5) == 0)
2494 vs
->lsock
= unix_connect(display
+5);
2496 vs
->lsock
= inet_connect(display
, SOCK_STREAM
);
2497 if (-1 == vs
->lsock
) {
2502 vs
->csock
= vs
->lsock
;
2509 /* listen for connects */
2511 dpy
= qemu_malloc(256);
2512 if (strncmp(display
, "unix:", 5) == 0) {
2513 pstrcpy(dpy
, 256, "unix:");
2514 vs
->lsock
= unix_listen(display
+5, dpy
+5, 256-5);
2516 vs
->lsock
= inet_listen(display
, dpy
, 256, SOCK_STREAM
, 5900);
2518 if (-1 == vs
->lsock
) {
2527 return qemu_set_fd_handler2(vs
->lsock
, vnc_listen_poll
, vnc_listen_read
, NULL
, vs
);