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