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