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