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