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