]> git.proxmox.com Git - mirror_qemu.git/blame - vnc.c
cmpxchg8b fix - added cmpxchg16b
[mirror_qemu.git] / vnc.c
CommitLineData
7d510b8c
FB
1/*
2 * QEMU VNC display driver
5fafdf24 3 *
7d510b8c
FB
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
5fafdf24 6 *
7d510b8c
FB
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:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
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
23 * THE SOFTWARE.
24 */
25
87ecb68b
PB
26#include "qemu-common.h"
27#include "console.h"
28#include "sysemu.h"
6ca957f0 29#include "qemu_socket.h"
87ecb68b 30#include "qemu-timer.h"
24236869
FB
31
32#define VNC_REFRESH_INTERVAL (1000 / 30)
33
34#include "vnc_keysym.h"
35#include "keymaps.c"
70848515
TS
36#include "d3des.h"
37
8d5d2d4c
TS
38#if CONFIG_VNC_TLS
39#include <gnutls/gnutls.h>
40#include <gnutls/x509.h>
41#endif /* CONFIG_VNC_TLS */
70848515 42
8d5d2d4c
TS
43// #define _VNC_DEBUG 1
44
45#if _VNC_DEBUG
70848515 46#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
8d5d2d4c
TS
47
48#if CONFIG_VNC_TLS && _VNC_DEBUG >= 2
49/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
50static void vnc_debug_gnutls_log(int level, const char* str) {
51 VNC_DEBUG("%d %s", level, str);
52}
53#endif /* CONFIG_VNC_TLS && _VNC_DEBUG */
70848515
TS
54#else
55#define VNC_DEBUG(fmt, ...) do { } while (0)
56#endif
24236869 57
8d5d2d4c 58
24236869
FB
59typedef struct Buffer
60{
61 size_t capacity;
62 size_t offset;
60fe76f3 63 uint8_t *buffer;
24236869
FB
64} Buffer;
65
66typedef struct VncState VncState;
67
60fe76f3 68typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
24236869 69
3512779a
FB
70typedef void VncWritePixels(VncState *vs, void *data, int size);
71
72typedef void VncSendHextileTile(VncState *vs,
73 int x, int y, int w, int h,
5fafdf24 74 uint32_t *last_bg,
3512779a
FB
75 uint32_t *last_fg,
76 int *has_bg, int *has_fg);
77
99589bdc
FB
78#define VNC_MAX_WIDTH 2048
79#define VNC_MAX_HEIGHT 2048
80#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
81
70848515
TS
82#define VNC_AUTH_CHALLENGE_SIZE 16
83
84enum {
85 VNC_AUTH_INVALID = 0,
86 VNC_AUTH_NONE = 1,
87 VNC_AUTH_VNC = 2,
88 VNC_AUTH_RA2 = 5,
89 VNC_AUTH_RA2NE = 6,
90 VNC_AUTH_TIGHT = 16,
91 VNC_AUTH_ULTRA = 17,
92 VNC_AUTH_TLS = 18,
93 VNC_AUTH_VENCRYPT = 19
94};
95
8d5d2d4c
TS
96#if CONFIG_VNC_TLS
97enum {
98 VNC_WIREMODE_CLEAR,
99 VNC_WIREMODE_TLS,
100};
101
102enum {
103 VNC_AUTH_VENCRYPT_PLAIN = 256,
104 VNC_AUTH_VENCRYPT_TLSNONE = 257,
105 VNC_AUTH_VENCRYPT_TLSVNC = 258,
106 VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
107 VNC_AUTH_VENCRYPT_X509NONE = 260,
108 VNC_AUTH_VENCRYPT_X509VNC = 261,
109 VNC_AUTH_VENCRYPT_X509PLAIN = 262,
110};
3a702699
TS
111
112#if CONFIG_VNC_TLS
113#define X509_CA_CERT_FILE "ca-cert.pem"
114#define X509_CA_CRL_FILE "ca-crl.pem"
115#define X509_SERVER_KEY_FILE "server-key.pem"
116#define X509_SERVER_CERT_FILE "server-cert.pem"
117#endif
118
8d5d2d4c
TS
119#endif /* CONFIG_VNC_TLS */
120
24236869
FB
121struct VncState
122{
123 QEMUTimer *timer;
124 int lsock;
125 int csock;
126 DisplayState *ds;
127 int need_update;
128 int width;
129 int height;
99589bdc 130 uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
24236869 131 char *old_data;
3512779a 132 int depth; /* internal VNC frame buffer byte per pixel */
24236869
FB
133 int has_resize;
134 int has_hextile;
564c337e
FB
135 int has_pointer_type_change;
136 int absolute;
137 int last_x;
138 int last_y;
139
70848515
TS
140 int major;
141 int minor;
142
71cab5ca 143 char *display;
70848515
TS
144 char *password;
145 int auth;
8d5d2d4c
TS
146#if CONFIG_VNC_TLS
147 int subauth;
469b15c6 148 int x509verify;
6f43024c
TS
149
150 char *x509cacert;
151 char *x509cacrl;
152 char *x509cert;
153 char *x509key;
8d5d2d4c 154#endif
70848515 155 char challenge[VNC_AUTH_CHALLENGE_SIZE];
a9ce8590 156
8d5d2d4c
TS
157#if CONFIG_VNC_TLS
158 int wiremode;
159 gnutls_session_t tls_session;
160#endif
161
24236869
FB
162 Buffer output;
163 Buffer input;
164 kbd_layout_t *kbd_layout;
3512779a
FB
165 /* current output mode information */
166 VncWritePixels *write_pixels;
167 VncSendHextileTile *send_hextile_tile;
168 int pix_bpp, pix_big_endian;
169 int red_shift, red_max, red_shift1;
170 int green_shift, green_max, green_shift1;
171 int blue_shift, blue_max, blue_shift1;
24236869
FB
172
173 VncReadEvent *read_handler;
174 size_t read_handler_expect;
64f5a135
FB
175 /* input */
176 uint8_t modifiers_state[256];
24236869
FB
177};
178
a9ce8590
FB
179static VncState *vnc_state; /* needed for info vnc */
180
181void do_info_vnc(void)
182{
183 if (vnc_state == NULL)
184 term_printf("VNC server disabled\n");
185 else {
186 term_printf("VNC server active on: ");
187 term_print_filename(vnc_state->display);
188 term_printf("\n");
189
190 if (vnc_state->csock == -1)
191 term_printf("No client connected\n");
192 else
193 term_printf("Client connected\n");
194 }
195}
196
24236869
FB
197/* TODO
198 1) Get the queue working for IO.
199 2) there is some weirdness when using the -S option (the screen is grey
200 and not totally invalidated
201 3) resolutions > 1024
202*/
203
204static void vnc_write(VncState *vs, const void *data, size_t len);
205static void vnc_write_u32(VncState *vs, uint32_t value);
206static void vnc_write_s32(VncState *vs, int32_t value);
207static void vnc_write_u16(VncState *vs, uint16_t value);
208static void vnc_write_u8(VncState *vs, uint8_t value);
209static void vnc_flush(VncState *vs);
210static void vnc_update_client(void *opaque);
211static void vnc_client_read(void *opaque);
212
99589bdc
FB
213static inline void vnc_set_bit(uint32_t *d, int k)
214{
215 d[k >> 5] |= 1 << (k & 0x1f);
216}
217
218static inline void vnc_clear_bit(uint32_t *d, int k)
219{
220 d[k >> 5] &= ~(1 << (k & 0x1f));
221}
222
223static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
224{
225 int j;
226
227 j = 0;
228 while (n >= 32) {
229 d[j++] = -1;
230 n -= 32;
231 }
5fafdf24 232 if (n > 0)
99589bdc
FB
233 d[j++] = (1 << n) - 1;
234 while (j < nb_words)
235 d[j++] = 0;
236}
237
238static inline int vnc_get_bit(const uint32_t *d, int k)
239{
240 return (d[k >> 5] >> (k & 0x1f)) & 1;
241}
242
5fafdf24 243static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
99589bdc
FB
244 int nb_words)
245{
246 int i;
247 for(i = 0; i < nb_words; i++) {
248 if ((d1[i] & d2[i]) != 0)
249 return 1;
250 }
251 return 0;
252}
253
24236869
FB
254static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
255{
256 VncState *vs = ds->opaque;
257 int i;
258
259 h += y;
260
0486e8a7
AZ
261 /* round x down to ensure the loop only spans one 16-pixel block per,
262 iteration. otherwise, if (x % 16) != 0, the last iteration may span
263 two 16-pixel blocks but we only mark the first as dirty
264 */
265 w += (x % 16);
266 x -= (x % 16);
267
788abf8e
AZ
268 x = MIN(x, vs->width);
269 y = MIN(y, vs->height);
270 w = MIN(x + w, vs->width) - x;
271 h = MIN(y + h, vs->height) - y;
272
24236869
FB
273 for (; y < h; y++)
274 for (i = 0; i < w; i += 16)
99589bdc 275 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
24236869
FB
276}
277
278static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
279 int32_t encoding)
280{
281 vnc_write_u16(vs, x);
282 vnc_write_u16(vs, y);
283 vnc_write_u16(vs, w);
284 vnc_write_u16(vs, h);
285
286 vnc_write_s32(vs, encoding);
287}
288
289static void vnc_dpy_resize(DisplayState *ds, int w, int h)
290{
73e14b62 291 int size_changed;
24236869
FB
292 VncState *vs = ds->opaque;
293
294 ds->data = realloc(ds->data, w * h * vs->depth);
295 vs->old_data = realloc(vs->old_data, w * h * vs->depth);
296
297 if (ds->data == NULL || vs->old_data == NULL) {
298 fprintf(stderr, "vnc: memory allocation failed\n");
299 exit(1);
300 }
301
a528b80c
AZ
302 if (ds->depth != vs->depth * 8) {
303 ds->depth = vs->depth * 8;
304 console_color_init(ds);
305 }
73e14b62 306 size_changed = ds->width != w || ds->height != h;
24236869
FB
307 ds->width = w;
308 ds->height = h;
309 ds->linesize = w * vs->depth;
73e14b62 310 if (vs->csock != -1 && vs->has_resize && size_changed) {
24236869
FB
311 vnc_write_u8(vs, 0); /* msg id */
312 vnc_write_u8(vs, 0);
313 vnc_write_u16(vs, 1); /* number of rects */
314 vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
315 vnc_flush(vs);
316 vs->width = ds->width;
317 vs->height = ds->height;
318 }
319}
320
3512779a
FB
321/* fastest code */
322static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
323{
324 vnc_write(vs, pixels, size);
325}
326
327/* slowest but generic code. */
328static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
329{
330 unsigned int r, g, b;
331
332 r = (v >> vs->red_shift1) & vs->red_max;
333 g = (v >> vs->green_shift1) & vs->green_max;
334 b = (v >> vs->blue_shift1) & vs->blue_max;
5fafdf24
TS
335 v = (r << vs->red_shift) |
336 (g << vs->green_shift) |
3512779a
FB
337 (b << vs->blue_shift);
338 switch(vs->pix_bpp) {
339 case 1:
340 buf[0] = v;
341 break;
342 case 2:
343 if (vs->pix_big_endian) {
344 buf[0] = v >> 8;
345 buf[1] = v;
346 } else {
347 buf[1] = v >> 8;
348 buf[0] = v;
349 }
350 break;
351 default:
352 case 4:
353 if (vs->pix_big_endian) {
354 buf[0] = v >> 24;
355 buf[1] = v >> 16;
356 buf[2] = v >> 8;
357 buf[3] = v;
358 } else {
359 buf[3] = v >> 24;
360 buf[2] = v >> 16;
361 buf[1] = v >> 8;
362 buf[0] = v;
363 }
364 break;
365 }
366}
367
368static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
369{
370 uint32_t *pixels = pixels1;
371 uint8_t buf[4];
372 int n, i;
373
374 n = size >> 2;
375 for(i = 0; i < n; i++) {
376 vnc_convert_pixel(vs, buf, pixels[i]);
377 vnc_write(vs, buf, vs->pix_bpp);
378 }
379}
380
24236869
FB
381static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
382{
383 int i;
60fe76f3 384 uint8_t *row;
24236869
FB
385
386 vnc_framebuffer_update(vs, x, y, w, h, 0);
387
388 row = vs->ds->data + y * vs->ds->linesize + x * vs->depth;
389 for (i = 0; i < h; i++) {
3512779a 390 vs->write_pixels(vs, row, w * vs->depth);
24236869
FB
391 row += vs->ds->linesize;
392 }
393}
394
395static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
396{
397 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
398 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
399}
400
401#define BPP 8
402#include "vnchextile.h"
403#undef BPP
404
405#define BPP 16
406#include "vnchextile.h"
407#undef BPP
408
409#define BPP 32
410#include "vnchextile.h"
411#undef BPP
412
3512779a
FB
413#define GENERIC
414#define BPP 32
415#include "vnchextile.h"
416#undef BPP
417#undef GENERIC
418
24236869
FB
419static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
420{
421 int i, j;
422 int has_fg, has_bg;
423 uint32_t last_fg32, last_bg32;
24236869
FB
424
425 vnc_framebuffer_update(vs, x, y, w, h, 5);
426
427 has_fg = has_bg = 0;
428 for (j = y; j < (y + h); j += 16) {
429 for (i = x; i < (x + w); i += 16) {
5fafdf24 430 vs->send_hextile_tile(vs, i, j,
3512779a
FB
431 MIN(16, x + w - i), MIN(16, y + h - j),
432 &last_bg32, &last_fg32, &has_bg, &has_fg);
24236869
FB
433 }
434 }
435}
436
437static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
438{
439 if (vs->has_hextile)
440 send_framebuffer_update_hextile(vs, x, y, w, h);
441 else
442 send_framebuffer_update_raw(vs, x, y, w, h);
443}
444
445static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
446{
447 int src, dst;
60fe76f3
TS
448 uint8_t *src_row;
449 uint8_t *dst_row;
24236869
FB
450 char *old_row;
451 int y = 0;
452 int pitch = ds->linesize;
453 VncState *vs = ds->opaque;
454
455 vnc_update_client(vs);
456
457 if (dst_y > src_y) {
458 y = h - 1;
459 pitch = -pitch;
460 }
461
462 src = (ds->linesize * (src_y + y) + vs->depth * src_x);
463 dst = (ds->linesize * (dst_y + y) + vs->depth * dst_x);
464
465 src_row = ds->data + src;
466 dst_row = ds->data + dst;
467 old_row = vs->old_data + dst;
468
469 for (y = 0; y < h; y++) {
470 memmove(old_row, src_row, w * vs->depth);
471 memmove(dst_row, src_row, w * vs->depth);
472 src_row += pitch;
473 dst_row += pitch;
474 old_row += pitch;
475 }
476
477 vnc_write_u8(vs, 0); /* msg id */
478 vnc_write_u8(vs, 0);
479 vnc_write_u16(vs, 1); /* number of rects */
480 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, 1);
481 vnc_write_u16(vs, src_x);
482 vnc_write_u16(vs, src_y);
483 vnc_flush(vs);
484}
485
486static int find_dirty_height(VncState *vs, int y, int last_x, int x)
487{
488 int h;
489
490 for (h = 1; h < (vs->height - y); h++) {
491 int tmp_x;
99589bdc 492 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
24236869
FB
493 break;
494 for (tmp_x = last_x; tmp_x < x; tmp_x++)
99589bdc 495 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
24236869
FB
496 }
497
498 return h;
499}
500
501static void vnc_update_client(void *opaque)
502{
503 VncState *vs = opaque;
504
505 if (vs->need_update && vs->csock != -1) {
506 int y;
60fe76f3 507 uint8_t *row;
24236869 508 char *old_row;
99589bdc 509 uint32_t width_mask[VNC_DIRTY_WORDS];
24236869
FB
510 int n_rectangles;
511 int saved_offset;
512 int has_dirty = 0;
513
a0ecfb73
AZ
514 vga_hw_update();
515
99589bdc 516 vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
24236869
FB
517
518 /* Walk through the dirty map and eliminate tiles that
519 really aren't dirty */
520 row = vs->ds->data;
521 old_row = vs->old_data;
522
523 for (y = 0; y < vs->height; y++) {
99589bdc 524 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
24236869 525 int x;
60fe76f3
TS
526 uint8_t *ptr;
527 char *old_ptr;
24236869
FB
528
529 ptr = row;
60fe76f3 530 old_ptr = (char*)old_row;
24236869
FB
531
532 for (x = 0; x < vs->ds->width; x += 16) {
533 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
99589bdc 534 vnc_clear_bit(vs->dirty_row[y], (x / 16));
24236869
FB
535 } else {
536 has_dirty = 1;
537 memcpy(old_ptr, ptr, 16 * vs->depth);
538 }
539
540 ptr += 16 * vs->depth;
541 old_ptr += 16 * vs->depth;
542 }
543 }
544
545 row += vs->ds->linesize;
546 old_row += vs->ds->linesize;
547 }
548
549 if (!has_dirty) {
550 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
551 return;
552 }
553
554 /* Count rectangles */
555 n_rectangles = 0;
556 vnc_write_u8(vs, 0); /* msg id */
557 vnc_write_u8(vs, 0);
558 saved_offset = vs->output.offset;
559 vnc_write_u16(vs, 0);
560
561 for (y = 0; y < vs->height; y++) {
562 int x;
563 int last_x = -1;
564 for (x = 0; x < vs->width / 16; x++) {
99589bdc 565 if (vnc_get_bit(vs->dirty_row[y], x)) {
24236869
FB
566 if (last_x == -1) {
567 last_x = x;
568 }
99589bdc 569 vnc_clear_bit(vs->dirty_row[y], x);
24236869
FB
570 } else {
571 if (last_x != -1) {
572 int h = find_dirty_height(vs, y, last_x, x);
573 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
574 n_rectangles++;
575 }
576 last_x = -1;
577 }
578 }
579 if (last_x != -1) {
580 int h = find_dirty_height(vs, y, last_x, x);
581 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
582 n_rectangles++;
583 }
584 }
585 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
586 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
587 vnc_flush(vs);
588
589 }
24236869 590
a0ecfb73
AZ
591 if (vs->csock != -1) {
592 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
24236869 593 }
24236869 594
24236869
FB
595}
596
597static int vnc_listen_poll(void *opaque)
598{
599 VncState *vs = opaque;
600 if (vs->csock == -1)
601 return 1;
602 return 0;
603}
604
605static void buffer_reserve(Buffer *buffer, size_t len)
606{
607 if ((buffer->capacity - buffer->offset) < len) {
608 buffer->capacity += (len + 1024);
609 buffer->buffer = realloc(buffer->buffer, buffer->capacity);
610 if (buffer->buffer == NULL) {
611 fprintf(stderr, "vnc: out of memory\n");
612 exit(1);
613 }
614 }
615}
616
617static int buffer_empty(Buffer *buffer)
618{
619 return buffer->offset == 0;
620}
621
60fe76f3 622static uint8_t *buffer_end(Buffer *buffer)
24236869
FB
623{
624 return buffer->buffer + buffer->offset;
625}
626
627static void buffer_reset(Buffer *buffer)
628{
629 buffer->offset = 0;
630}
631
632static void buffer_append(Buffer *buffer, const void *data, size_t len)
633{
634 memcpy(buffer->buffer + buffer->offset, data, len);
635 buffer->offset += len;
636}
637
6ca957f0 638static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
24236869
FB
639{
640 if (ret == 0 || ret == -1) {
ea01e5fd
AZ
641 if (ret == -1) {
642 switch (last_errno) {
643 case EINTR:
644 case EAGAIN:
645#ifdef _WIN32
646 case WSAEWOULDBLOCK:
647#endif
648 return 0;
649 default:
650 break;
651 }
652 }
24236869 653
8d5d2d4c 654 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
24236869 655 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
6ca957f0 656 closesocket(vs->csock);
24236869
FB
657 vs->csock = -1;
658 buffer_reset(&vs->input);
659 buffer_reset(&vs->output);
660 vs->need_update = 0;
8d5d2d4c
TS
661#if CONFIG_VNC_TLS
662 if (vs->tls_session) {
663 gnutls_deinit(vs->tls_session);
664 vs->tls_session = NULL;
665 }
666 vs->wiremode = VNC_WIREMODE_CLEAR;
667#endif /* CONFIG_VNC_TLS */
24236869
FB
668 return 0;
669 }
670 return ret;
671}
672
673static void vnc_client_error(VncState *vs)
674{
6ca957f0 675 vnc_client_io_error(vs, -1, EINVAL);
24236869
FB
676}
677
678static void vnc_client_write(void *opaque)
679{
ceb5caaf 680 long ret;
24236869
FB
681 VncState *vs = opaque;
682
8d5d2d4c
TS
683#if CONFIG_VNC_TLS
684 if (vs->tls_session) {
685 ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);
686 if (ret < 0) {
687 if (ret == GNUTLS_E_AGAIN)
688 errno = EAGAIN;
689 else
690 errno = EIO;
691 ret = -1;
692 }
693 } else
694#endif /* CONFIG_VNC_TLS */
695 ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);
6ca957f0 696 ret = vnc_client_io_error(vs, ret, socket_error());
24236869
FB
697 if (!ret)
698 return;
699
700 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
701 vs->output.offset -= ret;
702
703 if (vs->output.offset == 0) {
704 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
705 }
706}
707
708static void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
709{
710 vs->read_handler = func;
711 vs->read_handler_expect = expecting;
712}
713
714static void vnc_client_read(void *opaque)
715{
716 VncState *vs = opaque;
ceb5caaf 717 long ret;
24236869
FB
718
719 buffer_reserve(&vs->input, 4096);
720
8d5d2d4c
TS
721#if CONFIG_VNC_TLS
722 if (vs->tls_session) {
723 ret = gnutls_read(vs->tls_session, buffer_end(&vs->input), 4096);
724 if (ret < 0) {
725 if (ret == GNUTLS_E_AGAIN)
726 errno = EAGAIN;
727 else
728 errno = EIO;
729 ret = -1;
730 }
731 } else
732#endif /* CONFIG_VNC_TLS */
733 ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);
6ca957f0 734 ret = vnc_client_io_error(vs, ret, socket_error());
24236869
FB
735 if (!ret)
736 return;
737
738 vs->input.offset += ret;
739
740 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
741 size_t len = vs->read_handler_expect;
742 int ret;
743
744 ret = vs->read_handler(vs, vs->input.buffer, len);
745 if (vs->csock == -1)
746 return;
747
748 if (!ret) {
749 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
750 vs->input.offset -= len;
751 } else {
752 vs->read_handler_expect = ret;
753 }
754 }
755}
756
757static void vnc_write(VncState *vs, const void *data, size_t len)
758{
759 buffer_reserve(&vs->output, len);
760
761 if (buffer_empty(&vs->output)) {
762 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
763 }
764
765 buffer_append(&vs->output, data, len);
766}
767
768static void vnc_write_s32(VncState *vs, int32_t value)
769{
770 vnc_write_u32(vs, *(uint32_t *)&value);
771}
772
773static void vnc_write_u32(VncState *vs, uint32_t value)
774{
775 uint8_t buf[4];
776
777 buf[0] = (value >> 24) & 0xFF;
778 buf[1] = (value >> 16) & 0xFF;
779 buf[2] = (value >> 8) & 0xFF;
780 buf[3] = value & 0xFF;
781
782 vnc_write(vs, buf, 4);
783}
784
785static void vnc_write_u16(VncState *vs, uint16_t value)
786{
64f5a135 787 uint8_t buf[2];
24236869
FB
788
789 buf[0] = (value >> 8) & 0xFF;
790 buf[1] = value & 0xFF;
791
792 vnc_write(vs, buf, 2);
793}
794
795static void vnc_write_u8(VncState *vs, uint8_t value)
796{
797 vnc_write(vs, (char *)&value, 1);
798}
799
800static void vnc_flush(VncState *vs)
801{
802 if (vs->output.offset)
803 vnc_client_write(vs);
804}
805
64f5a135 806static uint8_t read_u8(uint8_t *data, size_t offset)
24236869
FB
807{
808 return data[offset];
809}
810
64f5a135 811static uint16_t read_u16(uint8_t *data, size_t offset)
24236869
FB
812{
813 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
814}
815
64f5a135 816static int32_t read_s32(uint8_t *data, size_t offset)
24236869
FB
817{
818 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
819 (data[offset + 2] << 8) | data[offset + 3]);
820}
821
64f5a135 822static uint32_t read_u32(uint8_t *data, size_t offset)
24236869
FB
823{
824 return ((data[offset] << 24) | (data[offset + 1] << 16) |
825 (data[offset + 2] << 8) | data[offset + 3]);
826}
827
8d5d2d4c 828#if CONFIG_VNC_TLS
9596ebb7
PB
829static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
830 const void *data,
831 size_t len) {
8d5d2d4c
TS
832 struct VncState *vs = (struct VncState *)transport;
833 int ret;
834
835 retry:
836 ret = send(vs->csock, data, len, 0);
837 if (ret < 0) {
838 if (errno == EINTR)
839 goto retry;
840 return -1;
841 }
842 return ret;
843}
844
845
9596ebb7
PB
846static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
847 void *data,
848 size_t len) {
8d5d2d4c
TS
849 struct VncState *vs = (struct VncState *)transport;
850 int ret;
851
852 retry:
853 ret = recv(vs->csock, data, len, 0);
854 if (ret < 0) {
855 if (errno == EINTR)
856 goto retry;
857 return -1;
858 }
859 return ret;
860}
861#endif /* CONFIG_VNC_TLS */
862
60fe76f3 863static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
24236869
FB
864{
865}
866
564c337e
FB
867static void check_pointer_type_change(VncState *vs, int absolute)
868{
869 if (vs->has_pointer_type_change && vs->absolute != absolute) {
870 vnc_write_u8(vs, 0);
871 vnc_write_u8(vs, 0);
872 vnc_write_u16(vs, 1);
873 vnc_framebuffer_update(vs, absolute, 0,
874 vs->ds->width, vs->ds->height, -257);
875 vnc_flush(vs);
876 }
877 vs->absolute = absolute;
878}
879
24236869
FB
880static void pointer_event(VncState *vs, int button_mask, int x, int y)
881{
882 int buttons = 0;
883 int dz = 0;
884
885 if (button_mask & 0x01)
886 buttons |= MOUSE_EVENT_LBUTTON;
887 if (button_mask & 0x02)
888 buttons |= MOUSE_EVENT_MBUTTON;
889 if (button_mask & 0x04)
890 buttons |= MOUSE_EVENT_RBUTTON;
891 if (button_mask & 0x08)
892 dz = -1;
893 if (button_mask & 0x10)
894 dz = 1;
564c337e
FB
895
896 if (vs->absolute) {
b94ed577
AJ
897 kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
898 y * 0x7FFF / (vs->ds->height - 1),
24236869 899 dz, buttons);
564c337e
FB
900 } else if (vs->has_pointer_type_change) {
901 x -= 0x7FFF;
902 y -= 0x7FFF;
24236869 903
564c337e
FB
904 kbd_mouse_event(x, y, dz, buttons);
905 } else {
906 if (vs->last_x != -1)
907 kbd_mouse_event(x - vs->last_x,
908 y - vs->last_y,
909 dz, buttons);
910 vs->last_x = x;
911 vs->last_y = y;
24236869 912 }
564c337e
FB
913
914 check_pointer_type_change(vs, kbd_mouse_is_absolute());
24236869
FB
915}
916
64f5a135
FB
917static void reset_keys(VncState *vs)
918{
919 int i;
920 for(i = 0; i < 256; i++) {
921 if (vs->modifiers_state[i]) {
922 if (i & 0x80)
923 kbd_put_keycode(0xe0);
924 kbd_put_keycode(i | 0x80);
925 vs->modifiers_state[i] = 0;
926 }
927 }
928}
929
a528b80c
AZ
930static void press_key(VncState *vs, int keysym)
931{
932 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) & 0x7f);
933 kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
934}
935
bdbd7676 936static void do_key_event(VncState *vs, int down, uint32_t sym)
24236869
FB
937{
938 int keycode;
939
940 keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
3b46e624 941
64f5a135
FB
942 /* QEMU console switch */
943 switch(keycode) {
944 case 0x2a: /* Left Shift */
945 case 0x36: /* Right Shift */
946 case 0x1d: /* Left CTRL */
947 case 0x9d: /* Right CTRL */
948 case 0x38: /* Left ALT */
949 case 0xb8: /* Right ALT */
950 if (down)
951 vs->modifiers_state[keycode] = 1;
952 else
953 vs->modifiers_state[keycode] = 0;
954 break;
5fafdf24 955 case 0x02 ... 0x0a: /* '1' to '9' keys */
64f5a135
FB
956 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
957 /* Reset the modifiers sent to the current console */
958 reset_keys(vs);
959 console_select(keycode - 0x02);
960 return;
961 }
962 break;
4d3b6f6e 963 case 0x3a: /* CapsLock */
a528b80c
AZ
964 case 0x45: /* NumLock */
965 if (!down)
966 vs->modifiers_state[keycode] ^= 1;
967 break;
968 }
969
970 if (keycode_is_keypad(vs->kbd_layout, keycode)) {
971 /* If the numlock state needs to change then simulate an additional
972 keypress before sending this one. This will happen if the user
973 toggles numlock away from the VNC window.
974 */
975 if (keysym_is_numlock(vs->kbd_layout, sym & 0xFFFF)) {
976 if (!vs->modifiers_state[0x45]) {
977 vs->modifiers_state[0x45] = 1;
978 press_key(vs, 0xff7f);
979 }
980 } else {
981 if (vs->modifiers_state[0x45]) {
982 vs->modifiers_state[0x45] = 0;
983 press_key(vs, 0xff7f);
984 }
985 }
64f5a135 986 }
24236869 987
64f5a135
FB
988 if (is_graphic_console()) {
989 if (keycode & 0x80)
990 kbd_put_keycode(0xe0);
991 if (down)
992 kbd_put_keycode(keycode & 0x7f);
993 else
994 kbd_put_keycode(keycode | 0x80);
995 } else {
996 /* QEMU console emulation */
997 if (down) {
998 switch (keycode) {
999 case 0x2a: /* Left Shift */
1000 case 0x36: /* Right Shift */
1001 case 0x1d: /* Left CTRL */
1002 case 0x9d: /* Right CTRL */
1003 case 0x38: /* Left ALT */
1004 case 0xb8: /* Right ALT */
1005 break;
1006 case 0xc8:
1007 kbd_put_keysym(QEMU_KEY_UP);
1008 break;
1009 case 0xd0:
1010 kbd_put_keysym(QEMU_KEY_DOWN);
1011 break;
1012 case 0xcb:
1013 kbd_put_keysym(QEMU_KEY_LEFT);
1014 break;
1015 case 0xcd:
1016 kbd_put_keysym(QEMU_KEY_RIGHT);
1017 break;
1018 case 0xd3:
1019 kbd_put_keysym(QEMU_KEY_DELETE);
1020 break;
1021 case 0xc7:
1022 kbd_put_keysym(QEMU_KEY_HOME);
1023 break;
1024 case 0xcf:
1025 kbd_put_keysym(QEMU_KEY_END);
1026 break;
1027 case 0xc9:
1028 kbd_put_keysym(QEMU_KEY_PAGEUP);
1029 break;
1030 case 0xd1:
1031 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1032 break;
1033 default:
1034 kbd_put_keysym(sym);
1035 break;
1036 }
1037 }
1038 }
24236869
FB
1039}
1040
bdbd7676
FB
1041static void key_event(VncState *vs, int down, uint32_t sym)
1042{
a528b80c 1043 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
bdbd7676
FB
1044 sym = sym - 'A' + 'a';
1045 do_key_event(vs, down, sym);
1046}
1047
24236869
FB
1048static void framebuffer_update_request(VncState *vs, int incremental,
1049 int x_position, int y_position,
1050 int w, int h)
1051{
cf2d385c
TS
1052 if (x_position > vs->ds->width)
1053 x_position = vs->ds->width;
1054 if (y_position > vs->ds->height)
1055 y_position = vs->ds->height;
1056 if (x_position + w >= vs->ds->width)
1057 w = vs->ds->width - x_position;
1058 if (y_position + h >= vs->ds->height)
1059 h = vs->ds->height - y_position;
1060
24236869
FB
1061 int i;
1062 vs->need_update = 1;
1063 if (!incremental) {
1064 char *old_row = vs->old_data + y_position * vs->ds->linesize;
1065
1066 for (i = 0; i < h; i++) {
5fafdf24 1067 vnc_set_bits(vs->dirty_row[y_position + i],
99589bdc 1068 (vs->ds->width / 16), VNC_DIRTY_WORDS);
24236869
FB
1069 memset(old_row, 42, vs->ds->width * vs->depth);
1070 old_row += vs->ds->linesize;
1071 }
1072 }
1073}
1074
1075static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1076{
1077 int i;
1078
1079 vs->has_hextile = 0;
1080 vs->has_resize = 0;
564c337e
FB
1081 vs->has_pointer_type_change = 0;
1082 vs->absolute = -1;
24236869
FB
1083 vs->ds->dpy_copy = NULL;
1084
1085 for (i = n_encodings - 1; i >= 0; i--) {
1086 switch (encodings[i]) {
1087 case 0: /* Raw */
1088 vs->has_hextile = 0;
1089 break;
1090 case 1: /* CopyRect */
1091 vs->ds->dpy_copy = vnc_copy;
1092 break;
1093 case 5: /* Hextile */
1094 vs->has_hextile = 1;
1095 break;
1096 case -223: /* DesktopResize */
1097 vs->has_resize = 1;
1098 break;
564c337e
FB
1099 case -257:
1100 vs->has_pointer_type_change = 1;
1101 break;
24236869
FB
1102 default:
1103 break;
1104 }
1105 }
564c337e
FB
1106
1107 check_pointer_type_change(vs, kbd_mouse_is_absolute());
24236869
FB
1108}
1109
3512779a
FB
1110static int compute_nbits(unsigned int val)
1111{
1112 int n;
1113 n = 0;
1114 while (val != 0) {
1115 n++;
1116 val >>= 1;
1117 }
1118 return n;
1119}
1120
24236869
FB
1121static void set_pixel_format(VncState *vs,
1122 int bits_per_pixel, int depth,
1123 int big_endian_flag, int true_color_flag,
1124 int red_max, int green_max, int blue_max,
1125 int red_shift, int green_shift, int blue_shift)
1126{
3512779a 1127 int host_big_endian_flag;
24236869 1128
3512779a
FB
1129#ifdef WORDS_BIGENDIAN
1130 host_big_endian_flag = 1;
1131#else
1132 host_big_endian_flag = 0;
1133#endif
1134 if (!true_color_flag) {
1135 fail:
24236869 1136 vnc_client_error(vs);
3512779a
FB
1137 return;
1138 }
5fafdf24 1139 if (bits_per_pixel == 32 &&
3512779a
FB
1140 host_big_endian_flag == big_endian_flag &&
1141 red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
1142 red_shift == 16 && green_shift == 8 && blue_shift == 0) {
1143 vs->depth = 4;
1144 vs->write_pixels = vnc_write_pixels_copy;
1145 vs->send_hextile_tile = send_hextile_tile_32;
5fafdf24
TS
1146 } else
1147 if (bits_per_pixel == 16 &&
3512779a
FB
1148 host_big_endian_flag == big_endian_flag &&
1149 red_max == 31 && green_max == 63 && blue_max == 31 &&
1150 red_shift == 11 && green_shift == 5 && blue_shift == 0) {
1151 vs->depth = 2;
1152 vs->write_pixels = vnc_write_pixels_copy;
1153 vs->send_hextile_tile = send_hextile_tile_16;
5fafdf24
TS
1154 } else
1155 if (bits_per_pixel == 8 &&
3512779a
FB
1156 red_max == 7 && green_max == 7 && blue_max == 3 &&
1157 red_shift == 5 && green_shift == 2 && blue_shift == 0) {
1158 vs->depth = 1;
1159 vs->write_pixels = vnc_write_pixels_copy;
1160 vs->send_hextile_tile = send_hextile_tile_8;
5fafdf24 1161 } else
3512779a
FB
1162 {
1163 /* generic and slower case */
1164 if (bits_per_pixel != 8 &&
1165 bits_per_pixel != 16 &&
1166 bits_per_pixel != 32)
1167 goto fail;
1168 vs->depth = 4;
1169 vs->red_shift = red_shift;
1170 vs->red_max = red_max;
1171 vs->red_shift1 = 24 - compute_nbits(red_max);
1172 vs->green_shift = green_shift;
1173 vs->green_max = green_max;
1174 vs->green_shift1 = 16 - compute_nbits(green_max);
1175 vs->blue_shift = blue_shift;
1176 vs->blue_max = blue_max;
1177 vs->blue_shift1 = 8 - compute_nbits(blue_max);
1178 vs->pix_bpp = bits_per_pixel / 8;
1179 vs->pix_big_endian = big_endian_flag;
1180 vs->write_pixels = vnc_write_pixels_generic;
1181 vs->send_hextile_tile = send_hextile_tile_generic;
1182 }
24236869
FB
1183
1184 vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
1185 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1186 memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);
1187
1188 vga_hw_invalidate();
1189 vga_hw_update();
1190}
1191
60fe76f3 1192static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
24236869
FB
1193{
1194 int i;
1195 uint16_t limit;
1196
1197 switch (data[0]) {
1198 case 0:
1199 if (len == 1)
1200 return 20;
1201
1202 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1203 read_u8(data, 6), read_u8(data, 7),
1204 read_u16(data, 8), read_u16(data, 10),
1205 read_u16(data, 12), read_u8(data, 14),
1206 read_u8(data, 15), read_u8(data, 16));
1207 break;
1208 case 2:
1209 if (len == 1)
1210 return 4;
1211
1212 if (len == 4)
1213 return 4 + (read_u16(data, 2) * 4);
1214
1215 limit = read_u16(data, 2);
1216 for (i = 0; i < limit; i++) {
1217 int32_t val = read_s32(data, 4 + (i * 4));
1218 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1219 }
1220
1221 set_encodings(vs, (int32_t *)(data + 4), limit);
1222 break;
1223 case 3:
1224 if (len == 1)
1225 return 10;
1226
1227 framebuffer_update_request(vs,
1228 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1229 read_u16(data, 6), read_u16(data, 8));
1230 break;
1231 case 4:
1232 if (len == 1)
1233 return 8;
1234
1235 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1236 break;
1237 case 5:
1238 if (len == 1)
1239 return 6;
1240
1241 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1242 break;
1243 case 6:
1244 if (len == 1)
1245 return 8;
1246
baa7666c
TS
1247 if (len == 8) {
1248 uint32_t dlen = read_u32(data, 4);
1249 if (dlen > 0)
1250 return 8 + dlen;
1251 }
24236869
FB
1252
1253 client_cut_text(vs, read_u32(data, 4), data + 8);
1254 break;
1255 default:
1256 printf("Msg: %d\n", data[0]);
1257 vnc_client_error(vs);
1258 break;
1259 }
5fafdf24 1260
24236869
FB
1261 vnc_read_when(vs, protocol_client_msg, 1);
1262 return 0;
1263}
1264
60fe76f3 1265static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869
FB
1266{
1267 char pad[3] = { 0, 0, 0 };
c35734b2
TS
1268 char buf[1024];
1269 int size;
24236869
FB
1270
1271 vs->width = vs->ds->width;
1272 vs->height = vs->ds->height;
1273 vnc_write_u16(vs, vs->ds->width);
1274 vnc_write_u16(vs, vs->ds->height);
1275
1276 vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */
1277 vnc_write_u8(vs, vs->depth * 8); /* depth */
3512779a
FB
1278#ifdef WORDS_BIGENDIAN
1279 vnc_write_u8(vs, 1); /* big-endian-flag */
1280#else
24236869 1281 vnc_write_u8(vs, 0); /* big-endian-flag */
3512779a 1282#endif
24236869
FB
1283 vnc_write_u8(vs, 1); /* true-color-flag */
1284 if (vs->depth == 4) {
1285 vnc_write_u16(vs, 0xFF); /* red-max */
1286 vnc_write_u16(vs, 0xFF); /* green-max */
1287 vnc_write_u16(vs, 0xFF); /* blue-max */
1288 vnc_write_u8(vs, 16); /* red-shift */
1289 vnc_write_u8(vs, 8); /* green-shift */
1290 vnc_write_u8(vs, 0); /* blue-shift */
3512779a 1291 vs->send_hextile_tile = send_hextile_tile_32;
24236869
FB
1292 } else if (vs->depth == 2) {
1293 vnc_write_u16(vs, 31); /* red-max */
1294 vnc_write_u16(vs, 63); /* green-max */
1295 vnc_write_u16(vs, 31); /* blue-max */
1296 vnc_write_u8(vs, 11); /* red-shift */
1297 vnc_write_u8(vs, 5); /* green-shift */
1298 vnc_write_u8(vs, 0); /* blue-shift */
3512779a 1299 vs->send_hextile_tile = send_hextile_tile_16;
24236869 1300 } else if (vs->depth == 1) {
3512779a
FB
1301 /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */
1302 vnc_write_u16(vs, 7); /* red-max */
24236869
FB
1303 vnc_write_u16(vs, 7); /* green-max */
1304 vnc_write_u16(vs, 3); /* blue-max */
1305 vnc_write_u8(vs, 5); /* red-shift */
1306 vnc_write_u8(vs, 2); /* green-shift */
1307 vnc_write_u8(vs, 0); /* blue-shift */
3512779a 1308 vs->send_hextile_tile = send_hextile_tile_8;
24236869 1309 }
3512779a 1310 vs->write_pixels = vnc_write_pixels_copy;
5fafdf24 1311
24236869
FB
1312 vnc_write(vs, pad, 3); /* padding */
1313
c35734b2
TS
1314 if (qemu_name)
1315 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1316 else
1317 size = snprintf(buf, sizeof(buf), "QEMU");
1318
1319 vnc_write_u32(vs, size);
1320 vnc_write(vs, buf, size);
24236869
FB
1321 vnc_flush(vs);
1322
1323 vnc_read_when(vs, protocol_client_msg, 1);
1324
1325 return 0;
1326}
1327
70848515
TS
1328static void make_challenge(VncState *vs)
1329{
1330 int i;
1331
1332 srand(time(NULL)+getpid()+getpid()*987654+rand());
1333
1334 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1335 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1336}
1337
60fe76f3 1338static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 1339{
60fe76f3 1340 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
70848515 1341 int i, j, pwlen;
60fe76f3 1342 unsigned char key[8];
70848515
TS
1343
1344 if (!vs->password || !vs->password[0]) {
1345 VNC_DEBUG("No password configured on server");
1346 vnc_write_u32(vs, 1); /* Reject auth */
1347 if (vs->minor >= 8) {
1348 static const char err[] = "Authentication failed";
1349 vnc_write_u32(vs, sizeof(err));
1350 vnc_write(vs, err, sizeof(err));
1351 }
1352 vnc_flush(vs);
1353 vnc_client_error(vs);
1354 return 0;
1355 }
1356
1357 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1358
1359 /* Calculate the expected challenge response */
1360 pwlen = strlen(vs->password);
1361 for (i=0; i<sizeof(key); i++)
1362 key[i] = i<pwlen ? vs->password[i] : 0;
1363 deskey(key, EN0);
1364 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1365 des(response+j, response+j);
1366
1367 /* Compare expected vs actual challenge response */
1368 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1369 VNC_DEBUG("Client challenge reponse did not match\n");
1370 vnc_write_u32(vs, 1); /* Reject auth */
1371 if (vs->minor >= 8) {
1372 static const char err[] = "Authentication failed";
1373 vnc_write_u32(vs, sizeof(err));
1374 vnc_write(vs, err, sizeof(err));
1375 }
1376 vnc_flush(vs);
1377 vnc_client_error(vs);
1378 } else {
1379 VNC_DEBUG("Accepting VNC challenge response\n");
1380 vnc_write_u32(vs, 0); /* Accept auth */
1381 vnc_flush(vs);
1382
1383 vnc_read_when(vs, protocol_client_init, 1);
1384 }
1385 return 0;
1386}
1387
1388static int start_auth_vnc(VncState *vs)
1389{
1390 make_challenge(vs);
1391 /* Send client a 'random' challenge */
1392 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1393 vnc_flush(vs);
1394
1395 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1396 return 0;
1397}
1398
8d5d2d4c
TS
1399
1400#if CONFIG_VNC_TLS
1401#define DH_BITS 1024
1402static gnutls_dh_params_t dh_params;
1403
1404static int vnc_tls_initialize(void)
1405{
1406 static int tlsinitialized = 0;
1407
1408 if (tlsinitialized)
1409 return 1;
1410
1411 if (gnutls_global_init () < 0)
1412 return 0;
1413
1414 /* XXX ought to re-generate diffie-hellmen params periodically */
1415 if (gnutls_dh_params_init (&dh_params) < 0)
1416 return 0;
1417 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1418 return 0;
1419
1420#if _VNC_DEBUG == 2
1421 gnutls_global_set_log_level(10);
1422 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1423#endif
1424
1425 tlsinitialized = 1;
1426
1427 return 1;
1428}
1429
1430static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1431{
1432 gnutls_anon_server_credentials anon_cred;
1433 int ret;
1434
1435 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1436 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1437 return NULL;
1438 }
1439
1440 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1441
1442 return anon_cred;
1443}
1444
1445
6f43024c 1446static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
3a702699
TS
1447{
1448 gnutls_certificate_credentials_t x509_cred;
1449 int ret;
6f43024c
TS
1450
1451 if (!vs->x509cacert) {
1452 VNC_DEBUG("No CA x509 certificate specified\n");
1453 return NULL;
1454 }
1455 if (!vs->x509cert) {
1456 VNC_DEBUG("No server x509 certificate specified\n");
1457 return NULL;
1458 }
1459 if (!vs->x509key) {
1460 VNC_DEBUG("No server private key specified\n");
1461 return NULL;
1462 }
3a702699
TS
1463
1464 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1465 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1466 return NULL;
1467 }
6f43024c
TS
1468 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
1469 vs->x509cacert,
1470 GNUTLS_X509_FMT_PEM)) < 0) {
3a702699
TS
1471 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1472 gnutls_certificate_free_credentials(x509_cred);
1473 return NULL;
1474 }
1475
6f43024c
TS
1476 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
1477 vs->x509cert,
1478 vs->x509key,
3a702699
TS
1479 GNUTLS_X509_FMT_PEM)) < 0) {
1480 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1481 gnutls_certificate_free_credentials(x509_cred);
1482 return NULL;
1483 }
1484
6f43024c
TS
1485 if (vs->x509cacrl) {
1486 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
1487 vs->x509cacrl,
1488 GNUTLS_X509_FMT_PEM)) < 0) {
3a702699
TS
1489 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1490 gnutls_certificate_free_credentials(x509_cred);
1491 return NULL;
1492 }
1493 }
1494
1495 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1496
1497 return x509_cred;
1498}
1499
469b15c6
TS
1500static int vnc_validate_certificate(struct VncState *vs)
1501{
1502 int ret;
1503 unsigned int status;
1504 const gnutls_datum_t *certs;
1505 unsigned int nCerts, i;
1506 time_t now;
1507
1508 VNC_DEBUG("Validating client certificate\n");
1509 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1510 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1511 return -1;
1512 }
1513
1514 if ((now = time(NULL)) == ((time_t)-1)) {
1515 return -1;
1516 }
1517
1518 if (status != 0) {
1519 if (status & GNUTLS_CERT_INVALID)
1520 VNC_DEBUG("The certificate is not trusted.\n");
1521
1522 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1523 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1524
1525 if (status & GNUTLS_CERT_REVOKED)
1526 VNC_DEBUG("The certificate has been revoked.\n");
1527
1528 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1529 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1530
1531 return -1;
1532 } else {
1533 VNC_DEBUG("Certificate is valid!\n");
1534 }
1535
1536 /* Only support x509 for now */
1537 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1538 return -1;
1539
1540 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1541 return -1;
1542
1543 for (i = 0 ; i < nCerts ; i++) {
1544 gnutls_x509_crt_t cert;
1545 VNC_DEBUG ("Checking certificate chain %d\n", i);
1546 if (gnutls_x509_crt_init (&cert) < 0)
1547 return -1;
1548
1549 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1550 gnutls_x509_crt_deinit (cert);
1551 return -1;
1552 }
1553
1554 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1555 VNC_DEBUG("The certificate has expired\n");
1556 gnutls_x509_crt_deinit (cert);
1557 return -1;
1558 }
1559
1560 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1561 VNC_DEBUG("The certificate is not yet activated\n");
1562 gnutls_x509_crt_deinit (cert);
1563 return -1;
1564 }
1565
1566 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1567 VNC_DEBUG("The certificate is not yet activated\n");
1568 gnutls_x509_crt_deinit (cert);
1569 return -1;
1570 }
1571
1572 gnutls_x509_crt_deinit (cert);
1573 }
1574
1575 return 0;
1576}
1577
1578
8d5d2d4c
TS
1579static int start_auth_vencrypt_subauth(VncState *vs)
1580{
1581 switch (vs->subauth) {
1582 case VNC_AUTH_VENCRYPT_TLSNONE:
3a702699 1583 case VNC_AUTH_VENCRYPT_X509NONE:
8d5d2d4c
TS
1584 VNC_DEBUG("Accept TLS auth none\n");
1585 vnc_write_u32(vs, 0); /* Accept auth completion */
1586 vnc_read_when(vs, protocol_client_init, 1);
1587 break;
1588
1589 case VNC_AUTH_VENCRYPT_TLSVNC:
3a702699 1590 case VNC_AUTH_VENCRYPT_X509VNC:
8d5d2d4c
TS
1591 VNC_DEBUG("Start TLS auth VNC\n");
1592 return start_auth_vnc(vs);
1593
1594 default: /* Should not be possible, but just in case */
1595 VNC_DEBUG("Reject auth %d\n", vs->auth);
1596 vnc_write_u8(vs, 1);
1597 if (vs->minor >= 8) {
1598 static const char err[] = "Unsupported authentication type";
1599 vnc_write_u32(vs, sizeof(err));
1600 vnc_write(vs, err, sizeof(err));
1601 }
1602 vnc_client_error(vs);
1603 }
1604
1605 return 0;
1606}
1607
1608static void vnc_handshake_io(void *opaque);
1609
1610static int vnc_continue_handshake(struct VncState *vs) {
1611 int ret;
1612
1613 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1614 if (!gnutls_error_is_fatal(ret)) {
1615 VNC_DEBUG("Handshake interrupted (blocking)\n");
1616 if (!gnutls_record_get_direction(vs->tls_session))
1617 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1618 else
1619 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1620 return 0;
1621 }
1622 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1623 vnc_client_error(vs);
1624 return -1;
1625 }
1626
469b15c6
TS
1627 if (vs->x509verify) {
1628 if (vnc_validate_certificate(vs) < 0) {
1629 VNC_DEBUG("Client verification failed\n");
1630 vnc_client_error(vs);
1631 return -1;
1632 } else {
1633 VNC_DEBUG("Client verification passed\n");
1634 }
1635 }
1636
8d5d2d4c
TS
1637 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1638 vs->wiremode = VNC_WIREMODE_TLS;
1639 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1640
1641 return start_auth_vencrypt_subauth(vs);
1642}
1643
1644static void vnc_handshake_io(void *opaque) {
1645 struct VncState *vs = (struct VncState *)opaque;
1646
1647 VNC_DEBUG("Handshake IO continue\n");
1648 vnc_continue_handshake(vs);
1649}
1650
3a702699
TS
1651#define NEED_X509_AUTH(vs) \
1652 ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1653 (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1654 (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
1655
1656
8d5d2d4c
TS
1657static int vnc_start_tls(struct VncState *vs) {
1658 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1659 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1660 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
3a702699 1661 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
8d5d2d4c
TS
1662
1663 VNC_DEBUG("Do TLS setup\n");
1664 if (vnc_tls_initialize() < 0) {
1665 VNC_DEBUG("Failed to init TLS\n");
1666 vnc_client_error(vs);
1667 return -1;
1668 }
1669 if (vs->tls_session == NULL) {
1670 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
1671 vnc_client_error(vs);
1672 return -1;
1673 }
1674
1675 if (gnutls_set_default_priority(vs->tls_session) < 0) {
1676 gnutls_deinit(vs->tls_session);
1677 vs->tls_session = NULL;
1678 vnc_client_error(vs);
1679 return -1;
1680 }
1681
3a702699 1682 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
8d5d2d4c
TS
1683 gnutls_deinit(vs->tls_session);
1684 vs->tls_session = NULL;
1685 vnc_client_error(vs);
1686 return -1;
1687 }
1688
1689 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
1690 gnutls_deinit(vs->tls_session);
1691 vs->tls_session = NULL;
1692 vnc_client_error(vs);
1693 return -1;
1694 }
1695
1696 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
1697 gnutls_deinit(vs->tls_session);
1698 vs->tls_session = NULL;
1699 vnc_client_error(vs);
1700 return -1;
1701 }
1702
3a702699 1703 if (NEED_X509_AUTH(vs)) {
6f43024c 1704 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
3a702699
TS
1705 if (!x509_cred) {
1706 gnutls_deinit(vs->tls_session);
1707 vs->tls_session = NULL;
1708 vnc_client_error(vs);
1709 return -1;
1710 }
1711 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
1712 gnutls_deinit(vs->tls_session);
1713 vs->tls_session = NULL;
1714 gnutls_certificate_free_credentials(x509_cred);
1715 vnc_client_error(vs);
1716 return -1;
1717 }
469b15c6
TS
1718 if (vs->x509verify) {
1719 VNC_DEBUG("Requesting a client certificate\n");
1720 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
1721 }
1722
3a702699
TS
1723 } else {
1724 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
1725 if (!anon_cred) {
1726 gnutls_deinit(vs->tls_session);
1727 vs->tls_session = NULL;
1728 vnc_client_error(vs);
1729 return -1;
1730 }
1731 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
1732 gnutls_deinit(vs->tls_session);
1733 vs->tls_session = NULL;
1734 gnutls_anon_free_server_credentials(anon_cred);
1735 vnc_client_error(vs);
1736 return -1;
1737 }
8d5d2d4c
TS
1738 }
1739
1740 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
1741 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
1742 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
1743 }
1744
1745 VNC_DEBUG("Start TLS handshake process\n");
1746 return vnc_continue_handshake(vs);
1747}
1748
60fe76f3 1749static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
8d5d2d4c
TS
1750{
1751 int auth = read_u32(data, 0);
1752
1753 if (auth != vs->subauth) {
1754 VNC_DEBUG("Rejecting auth %d\n", auth);
1755 vnc_write_u8(vs, 0); /* Reject auth */
1756 vnc_flush(vs);
1757 vnc_client_error(vs);
1758 } else {
1759 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
1760 vnc_write_u8(vs, 1); /* Accept auth */
1761 vnc_flush(vs);
1762
1763 if (vnc_start_tls(vs) < 0) {
1764 VNC_DEBUG("Failed to complete TLS\n");
1765 return 0;
1766 }
1767
1768 if (vs->wiremode == VNC_WIREMODE_TLS) {
1769 VNC_DEBUG("Starting VeNCrypt subauth\n");
1770 return start_auth_vencrypt_subauth(vs);
1771 } else {
1772 VNC_DEBUG("TLS handshake blocked\n");
1773 return 0;
1774 }
1775 }
1776 return 0;
1777}
1778
60fe76f3 1779static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
8d5d2d4c
TS
1780{
1781 if (data[0] != 0 ||
1782 data[1] != 2) {
1783 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
1784 vnc_write_u8(vs, 1); /* Reject version */
1785 vnc_flush(vs);
1786 vnc_client_error(vs);
1787 } else {
1788 VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
1789 vnc_write_u8(vs, 0); /* Accept version */
1790 vnc_write_u8(vs, 1); /* Number of sub-auths */
1791 vnc_write_u32(vs, vs->subauth); /* The supported auth */
1792 vnc_flush(vs);
1793 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
1794 }
1795 return 0;
1796}
1797
1798static int start_auth_vencrypt(VncState *vs)
1799{
1800 /* Send VeNCrypt version 0.2 */
1801 vnc_write_u8(vs, 0);
1802 vnc_write_u8(vs, 2);
1803
1804 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
1805 return 0;
1806}
1807#endif /* CONFIG_VNC_TLS */
1808
60fe76f3 1809static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
1810{
1811 /* We only advertise 1 auth scheme at a time, so client
1812 * must pick the one we sent. Verify this */
1813 if (data[0] != vs->auth) { /* Reject auth */
1814 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
1815 vnc_write_u32(vs, 1);
1816 if (vs->minor >= 8) {
1817 static const char err[] = "Authentication failed";
1818 vnc_write_u32(vs, sizeof(err));
1819 vnc_write(vs, err, sizeof(err));
1820 }
1821 vnc_client_error(vs);
1822 } else { /* Accept requested auth */
1823 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1824 switch (vs->auth) {
1825 case VNC_AUTH_NONE:
1826 VNC_DEBUG("Accept auth none\n");
a26c97ad
AZ
1827 if (vs->minor >= 8) {
1828 vnc_write_u32(vs, 0); /* Accept auth completion */
1829 vnc_flush(vs);
1830 }
70848515
TS
1831 vnc_read_when(vs, protocol_client_init, 1);
1832 break;
1833
1834 case VNC_AUTH_VNC:
1835 VNC_DEBUG("Start VNC auth\n");
1836 return start_auth_vnc(vs);
1837
8d5d2d4c
TS
1838#if CONFIG_VNC_TLS
1839 case VNC_AUTH_VENCRYPT:
1840 VNC_DEBUG("Accept VeNCrypt auth\n");;
1841 return start_auth_vencrypt(vs);
1842#endif /* CONFIG_VNC_TLS */
1843
70848515
TS
1844 default: /* Should not be possible, but just in case */
1845 VNC_DEBUG("Reject auth %d\n", vs->auth);
1846 vnc_write_u8(vs, 1);
1847 if (vs->minor >= 8) {
1848 static const char err[] = "Authentication failed";
1849 vnc_write_u32(vs, sizeof(err));
1850 vnc_write(vs, err, sizeof(err));
1851 }
1852 vnc_client_error(vs);
1853 }
1854 }
1855 return 0;
1856}
1857
60fe76f3 1858static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
1859{
1860 char local[13];
24236869
FB
1861
1862 memcpy(local, version, 12);
1863 local[12] = 0;
1864
70848515
TS
1865 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1866 VNC_DEBUG("Malformed protocol version %s\n", local);
24236869
FB
1867 vnc_client_error(vs);
1868 return 0;
1869 }
70848515
TS
1870 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1871 if (vs->major != 3 ||
1872 (vs->minor != 3 &&
b0566f4f 1873 vs->minor != 4 &&
70848515
TS
1874 vs->minor != 5 &&
1875 vs->minor != 7 &&
1876 vs->minor != 8)) {
1877 VNC_DEBUG("Unsupported client version\n");
1878 vnc_write_u32(vs, VNC_AUTH_INVALID);
1879 vnc_flush(vs);
1880 vnc_client_error(vs);
1881 return 0;
1882 }
b0566f4f 1883 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
1884 * as equivalent to v3.3 by servers
1885 */
b0566f4f 1886 if (vs->minor == 4 || vs->minor == 5)
70848515
TS
1887 vs->minor = 3;
1888
1889 if (vs->minor == 3) {
1890 if (vs->auth == VNC_AUTH_NONE) {
1891 VNC_DEBUG("Tell client auth none\n");
1892 vnc_write_u32(vs, vs->auth);
1893 vnc_flush(vs);
1894 vnc_read_when(vs, protocol_client_init, 1);
1895 } else if (vs->auth == VNC_AUTH_VNC) {
1896 VNC_DEBUG("Tell client VNC auth\n");
1897 vnc_write_u32(vs, vs->auth);
1898 vnc_flush(vs);
1899 start_auth_vnc(vs);
1900 } else {
1901 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
1902 vnc_write_u32(vs, VNC_AUTH_INVALID);
1903 vnc_flush(vs);
1904 vnc_client_error(vs);
1905 }
1906 } else {
1907 VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
1908 vnc_write_u8(vs, 1); /* num auth */
1909 vnc_write_u8(vs, vs->auth);
1910 vnc_read_when(vs, protocol_client_auth, 1);
1911 vnc_flush(vs);
1912 }
24236869
FB
1913
1914 return 0;
1915}
1916
3aa3eea3
AZ
1917static void vnc_connect(VncState *vs)
1918{
1919 VNC_DEBUG("New client on socket %d\n", vs->csock);
1920 socket_set_nonblock(vs->csock);
1921 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1922 vnc_write(vs, "RFB 003.008\n", 12);
1923 vnc_flush(vs);
1924 vnc_read_when(vs, protocol_version, 12);
1925 memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);
1926 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1927 vs->has_resize = 0;
1928 vs->has_hextile = 0;
1929 vs->ds->dpy_copy = NULL;
1930 vnc_update_client(vs);
1931}
1932
24236869
FB
1933static void vnc_listen_read(void *opaque)
1934{
1935 VncState *vs = opaque;
1936 struct sockaddr_in addr;
1937 socklen_t addrlen = sizeof(addr);
1938
9f60ad50
AZ
1939 /* Catch-up */
1940 vga_hw_update();
1941
24236869
FB
1942 vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1943 if (vs->csock != -1) {
3aa3eea3 1944 vnc_connect(vs);
24236869
FB
1945 }
1946}
1947
73fc9742
TS
1948extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
1949
71cab5ca 1950void vnc_display_init(DisplayState *ds)
24236869 1951{
24236869
FB
1952 VncState *vs;
1953
1954 vs = qemu_mallocz(sizeof(VncState));
1955 if (!vs)
1956 exit(1);
1957
1958 ds->opaque = vs;
a9ce8590 1959 vnc_state = vs;
71cab5ca 1960 vs->display = NULL;
70848515 1961 vs->password = NULL;
24236869
FB
1962
1963 vs->lsock = -1;
1964 vs->csock = -1;
1965 vs->depth = 4;
564c337e
FB
1966 vs->last_x = -1;
1967 vs->last_y = -1;
24236869
FB
1968
1969 vs->ds = ds;
1970
1971 if (!keyboard_layout)
1972 keyboard_layout = "en-us";
1973
1974 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
1975 if (!vs->kbd_layout)
1976 exit(1);
1977
a0ecfb73
AZ
1978 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
1979
73fc9742
TS
1980 vs->ds->data = NULL;
1981 vs->ds->dpy_update = vnc_dpy_update;
1982 vs->ds->dpy_resize = vnc_dpy_resize;
a0ecfb73 1983 vs->ds->dpy_refresh = NULL;
73fc9742
TS
1984
1985 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
24236869 1986
73fc9742 1987 vnc_dpy_resize(vs->ds, 640, 400);
71cab5ca
TS
1988}
1989
6f43024c
TS
1990#if CONFIG_VNC_TLS
1991static int vnc_set_x509_credential(VncState *vs,
1992 const char *certdir,
1993 const char *filename,
1994 char **cred,
1995 int ignoreMissing)
1996{
1997 struct stat sb;
1998
1999 if (*cred) {
2000 qemu_free(*cred);
2001 *cred = NULL;
2002 }
2003
2004 if (!(*cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2)))
2005 return -1;
2006
2007 strcpy(*cred, certdir);
2008 strcat(*cred, "/");
2009 strcat(*cred, filename);
2010
2011 VNC_DEBUG("Check %s\n", *cred);
2012 if (stat(*cred, &sb) < 0) {
2013 qemu_free(*cred);
2014 *cred = NULL;
2015 if (ignoreMissing && errno == ENOENT)
2016 return 0;
2017 return -1;
2018 }
2019
2020 return 0;
2021}
2022
2023static int vnc_set_x509_credential_dir(VncState *vs,
2024 const char *certdir)
2025{
2026 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2027 goto cleanup;
2028 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2029 goto cleanup;
2030 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2031 goto cleanup;
2032 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2033 goto cleanup;
2034
2035 return 0;
2036
2037 cleanup:
2038 qemu_free(vs->x509cacert);
2039 qemu_free(vs->x509cacrl);
2040 qemu_free(vs->x509cert);
2041 qemu_free(vs->x509key);
2042 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2043 return -1;
2044}
2045#endif /* CONFIG_VNC_TLS */
2046
71cab5ca
TS
2047void vnc_display_close(DisplayState *ds)
2048{
e25a5822 2049 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
71cab5ca
TS
2050
2051 if (vs->display) {
2052 qemu_free(vs->display);
2053 vs->display = NULL;
2054 }
2055 if (vs->lsock != -1) {
2056 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2057 close(vs->lsock);
2058 vs->lsock = -1;
2059 }
2060 if (vs->csock != -1) {
2061 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
2062 closesocket(vs->csock);
2063 vs->csock = -1;
2064 buffer_reset(&vs->input);
2065 buffer_reset(&vs->output);
2066 vs->need_update = 0;
8d5d2d4c
TS
2067#if CONFIG_VNC_TLS
2068 if (vs->tls_session) {
2069 gnutls_deinit(vs->tls_session);
2070 vs->tls_session = NULL;
2071 }
2072 vs->wiremode = VNC_WIREMODE_CLEAR;
2073#endif /* CONFIG_VNC_TLS */
71cab5ca 2074 }
70848515 2075 vs->auth = VNC_AUTH_INVALID;
8d5d2d4c
TS
2076#if CONFIG_VNC_TLS
2077 vs->subauth = VNC_AUTH_INVALID;
469b15c6 2078 vs->x509verify = 0;
8d5d2d4c 2079#endif
70848515
TS
2080}
2081
2082int vnc_display_password(DisplayState *ds, const char *password)
2083{
2084 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
2085
2086 if (vs->password) {
2087 qemu_free(vs->password);
2088 vs->password = NULL;
2089 }
2090 if (password && password[0]) {
2091 if (!(vs->password = qemu_strdup(password)))
2092 return -1;
2093 }
2094
2095 return 0;
71cab5ca
TS
2096}
2097
70848515 2098int vnc_display_open(DisplayState *ds, const char *display)
71cab5ca
TS
2099{
2100 struct sockaddr *addr;
2101 struct sockaddr_in iaddr;
2102#ifndef _WIN32
2103 struct sockaddr_un uaddr;
ea01e5fd 2104 const char *p;
71cab5ca
TS
2105#endif
2106 int reuse_addr, ret;
2107 socklen_t addrlen;
e25a5822 2108 VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
70848515
TS
2109 const char *options;
2110 int password = 0;
3aa3eea3 2111 int reverse = 0;
8d5d2d4c 2112#if CONFIG_VNC_TLS
3a702699 2113 int tls = 0, x509 = 0;
8d5d2d4c 2114#endif
71cab5ca
TS
2115
2116 vnc_display_close(ds);
70848515 2117 if (strcmp(display, "none") == 0)
71cab5ca 2118 return 0;
24236869 2119
70848515 2120 if (!(vs->display = strdup(display)))
71cab5ca 2121 return -1;
70848515
TS
2122
2123 options = display;
2124 while ((options = strchr(options, ','))) {
2125 options++;
469b15c6 2126 if (strncmp(options, "password", 8) == 0) {
70848515 2127 password = 1; /* Require password auth */
3aa3eea3
AZ
2128 } else if (strncmp(options, "reverse", 7) == 0) {
2129 reverse = 1;
8d5d2d4c 2130#if CONFIG_VNC_TLS
469b15c6 2131 } else if (strncmp(options, "tls", 3) == 0) {
8d5d2d4c 2132 tls = 1; /* Require TLS */
469b15c6 2133 } else if (strncmp(options, "x509", 4) == 0) {
6f43024c 2134 char *start, *end;
3a702699 2135 x509 = 1; /* Require x509 certificates */
6f43024c
TS
2136 if (strncmp(options, "x509verify", 10) == 0)
2137 vs->x509verify = 1; /* ...and verify client certs */
2138
2139 /* Now check for 'x509=/some/path' postfix
2140 * and use that to setup x509 certificate/key paths */
2141 start = strchr(options, '=');
2142 end = strchr(options, ',');
2143 if (start && (!end || (start < end))) {
2144 int len = end ? end-(start+1) : strlen(start+1);
2145 char *path = qemu_malloc(len+1);
2146 strncpy(path, start+1, len);
2147 path[len] = '\0';
2148 VNC_DEBUG("Trying certificate path '%s'\n", path);
2149 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2150 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2151 qemu_free(path);
2152 qemu_free(vs->display);
2153 vs->display = NULL;
2154 return -1;
2155 }
2156 qemu_free(path);
2157 } else {
2158 fprintf(stderr, "No certificate path provided\n");
2159 qemu_free(vs->display);
2160 vs->display = NULL;
2161 return -1;
2162 }
8d5d2d4c 2163#endif
469b15c6 2164 }
70848515
TS
2165 }
2166
2167 if (password) {
8d5d2d4c
TS
2168#if CONFIG_VNC_TLS
2169 if (tls) {
8d5d2d4c 2170 vs->auth = VNC_AUTH_VENCRYPT;
3a702699
TS
2171 if (x509) {
2172 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2173 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2174 } else {
2175 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2176 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2177 }
8d5d2d4c
TS
2178 } else {
2179#endif
2180 VNC_DEBUG("Initializing VNC server with password auth\n");
2181 vs->auth = VNC_AUTH_VNC;
2182#if CONFIG_VNC_TLS
2183 vs->subauth = VNC_AUTH_INVALID;
2184 }
2185#endif
70848515 2186 } else {
8d5d2d4c
TS
2187#if CONFIG_VNC_TLS
2188 if (tls) {
8d5d2d4c 2189 vs->auth = VNC_AUTH_VENCRYPT;
3a702699
TS
2190 if (x509) {
2191 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2192 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2193 } else {
2194 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2195 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2196 }
8d5d2d4c
TS
2197 } else {
2198#endif
2199 VNC_DEBUG("Initializing VNC server with no auth\n");
2200 vs->auth = VNC_AUTH_NONE;
2201#if CONFIG_VNC_TLS
2202 vs->subauth = VNC_AUTH_INVALID;
2203 }
2204#endif
70848515 2205 }
73fc9742 2206#ifndef _WIN32
70848515 2207 if (strstart(display, "unix:", &p)) {
73fc9742
TS
2208 addr = (struct sockaddr *)&uaddr;
2209 addrlen = sizeof(uaddr);
2210
2211 vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
2212 if (vs->lsock == -1) {
2213 fprintf(stderr, "Could not create socket\n");
71cab5ca
TS
2214 free(vs->display);
2215 vs->display = NULL;
2216 return -1;
73fc9742
TS
2217 }
2218
2219 uaddr.sun_family = AF_UNIX;
2220 memset(uaddr.sun_path, 0, 108);
2221 snprintf(uaddr.sun_path, 108, "%s", p);
2222
3aa3eea3
AZ
2223 if (!reverse) {
2224 unlink(uaddr.sun_path);
2225 }
73fc9742
TS
2226 } else
2227#endif
2228 {
2229 addr = (struct sockaddr *)&iaddr;
2230 addrlen = sizeof(iaddr);
2231
70848515 2232 if (parse_host_port(&iaddr, display) < 0) {
73fc9742 2233 fprintf(stderr, "Could not parse VNC address\n");
71cab5ca
TS
2234 free(vs->display);
2235 vs->display = NULL;
2236 return -1;
73fc9742 2237 }
71cab5ca 2238
3aa3eea3 2239 iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900));
73fc9742 2240
71cab5ca
TS
2241 vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
2242 if (vs->lsock == -1) {
2243 fprintf(stderr, "Could not create socket\n");
2244 free(vs->display);
2245 vs->display = NULL;
2246 return -1;
2247 }
2248
73fc9742
TS
2249 reuse_addr = 1;
2250 ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
2251 (const char *)&reuse_addr, sizeof(reuse_addr));
2252 if (ret == -1) {
2253 fprintf(stderr, "setsockopt() failed\n");
71cab5ca
TS
2254 close(vs->lsock);
2255 vs->lsock = -1;
2256 free(vs->display);
2257 vs->display = NULL;
2258 return -1;
73fc9742 2259 }
24236869
FB
2260 }
2261
3aa3eea3
AZ
2262 if (reverse) {
2263 if (connect(vs->lsock, addr, addrlen) == -1) {
2264 fprintf(stderr, "Connection to VNC client failed\n");
2265 close(vs->lsock);
2266 vs->lsock = -1;
2267 free(vs->display);
2268 vs->display = NULL;
2269 return -1;
2270 } else {
2271 vs->csock = vs->lsock;
2272 vs->lsock = -1;
2273 vnc_connect(vs);
2274 return 0;
2275 }
2276 }
2277
73fc9742 2278 if (bind(vs->lsock, addr, addrlen) == -1) {
24236869 2279 fprintf(stderr, "bind() failed\n");
71cab5ca
TS
2280 close(vs->lsock);
2281 vs->lsock = -1;
2282 free(vs->display);
2283 vs->display = NULL;
2284 return -1;
24236869
FB
2285 }
2286
2287 if (listen(vs->lsock, 1) == -1) {
2288 fprintf(stderr, "listen() failed\n");
71cab5ca
TS
2289 close(vs->lsock);
2290 vs->lsock = -1;
2291 free(vs->display);
2292 vs->display = NULL;
2293 return -1;
24236869
FB
2294 }
2295
71cab5ca 2296 return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
24236869 2297}