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