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