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