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