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