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