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