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