]> git.proxmox.com Git - qemu.git/blame - vnc.c
Add release tag for 0.10.1 release
[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:
1219 kbd_put_keysym(QEMU_KEY_UP);
1220 break;
1221 case 0xd0:
1222 kbd_put_keysym(QEMU_KEY_DOWN);
1223 break;
1224 case 0xcb:
1225 kbd_put_keysym(QEMU_KEY_LEFT);
1226 break;
1227 case 0xcd:
1228 kbd_put_keysym(QEMU_KEY_RIGHT);
1229 break;
1230 case 0xd3:
1231 kbd_put_keysym(QEMU_KEY_DELETE);
1232 break;
1233 case 0xc7:
1234 kbd_put_keysym(QEMU_KEY_HOME);
1235 break;
1236 case 0xcf:
1237 kbd_put_keysym(QEMU_KEY_END);
1238 break;
1239 case 0xc9:
1240 kbd_put_keysym(QEMU_KEY_PAGEUP);
1241 break;
1242 case 0xd1:
1243 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1244 break;
1245 default:
1246 kbd_put_keysym(sym);
1247 break;
1248 }
1249 }
1250 }
24236869
FB
1251}
1252
bdbd7676
FB
1253static void key_event(VncState *vs, int down, uint32_t sym)
1254{
9ca313aa
AL
1255 int keycode;
1256
a528b80c 1257 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
bdbd7676 1258 sym = sym - 'A' + 'a';
9ca313aa 1259
753b4053 1260 keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
9ca313aa
AL
1261 do_key_event(vs, down, keycode, sym);
1262}
1263
1264static void ext_key_event(VncState *vs, int down,
1265 uint32_t sym, uint16_t keycode)
1266{
1267 /* if the user specifies a keyboard layout, always use it */
1268 if (keyboard_layout)
1269 key_event(vs, down, sym);
1270 else
1271 do_key_event(vs, down, keycode, sym);
bdbd7676
FB
1272}
1273
24236869
FB
1274static void framebuffer_update_request(VncState *vs, int incremental,
1275 int x_position, int y_position,
1276 int w, int h)
1277{
0e1f5a0c
AL
1278 if (x_position > ds_get_width(vs->ds))
1279 x_position = ds_get_width(vs->ds);
1280 if (y_position > ds_get_height(vs->ds))
1281 y_position = ds_get_height(vs->ds);
1282 if (x_position + w >= ds_get_width(vs->ds))
1283 w = ds_get_width(vs->ds) - x_position;
1284 if (y_position + h >= ds_get_height(vs->ds))
1285 h = ds_get_height(vs->ds) - y_position;
cf2d385c 1286
24236869
FB
1287 int i;
1288 vs->need_update = 1;
1289 if (!incremental) {
0e1f5a0c 1290 char *old_row = vs->old_data + y_position * ds_get_linesize(vs->ds);
24236869
FB
1291
1292 for (i = 0; i < h; i++) {
5fafdf24 1293 vnc_set_bits(vs->dirty_row[y_position + i],
0e1f5a0c 1294 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
6cec5487 1295 memset(old_row, 42, ds_get_width(vs->ds) * ds_get_bytes_per_pixel(vs->ds));
0e1f5a0c 1296 old_row += ds_get_linesize(vs->ds);
24236869
FB
1297 }
1298 }
1299}
1300
9ca313aa
AL
1301static void send_ext_key_event_ack(VncState *vs)
1302{
1303 vnc_write_u8(vs, 0);
1304 vnc_write_u8(vs, 0);
1305 vnc_write_u16(vs, 1);
29fa4ed9
AL
1306 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1307 VNC_ENCODING_EXT_KEY_EVENT);
9ca313aa
AL
1308 vnc_flush(vs);
1309}
1310
429a8ed3 1311static void send_ext_audio_ack(VncState *vs)
1312{
1313 vnc_write_u8(vs, 0);
1314 vnc_write_u8(vs, 0);
1315 vnc_write_u16(vs, 1);
29fa4ed9
AL
1316 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1317 VNC_ENCODING_AUDIO);
429a8ed3 1318 vnc_flush(vs);
1319}
1320
24236869
FB
1321static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1322{
1323 int i;
29fa4ed9 1324 unsigned int enc = 0;
24236869 1325
059cef40 1326 vnc_zlib_init(vs);
29fa4ed9 1327 vs->features = 0;
fb437313
AL
1328 vs->vnc_encoding = 0;
1329 vs->tight_compression = 9;
1330 vs->tight_quality = 9;
564c337e 1331 vs->absolute = -1;
24236869
FB
1332
1333 for (i = n_encodings - 1; i >= 0; i--) {
29fa4ed9
AL
1334 enc = encodings[i];
1335 switch (enc) {
1336 case VNC_ENCODING_RAW:
fb437313 1337 vs->vnc_encoding = enc;
29fa4ed9
AL
1338 break;
1339 case VNC_ENCODING_COPYRECT:
753b4053 1340 vs->features |= VNC_FEATURE_COPYRECT_MASK;
29fa4ed9
AL
1341 break;
1342 case VNC_ENCODING_HEXTILE:
1343 vs->features |= VNC_FEATURE_HEXTILE_MASK;
fb437313 1344 vs->vnc_encoding = enc;
29fa4ed9 1345 break;
059cef40
AL
1346 case VNC_ENCODING_ZLIB:
1347 vs->features |= VNC_FEATURE_ZLIB_MASK;
1348 vs->vnc_encoding = enc;
1349 break;
29fa4ed9
AL
1350 case VNC_ENCODING_DESKTOPRESIZE:
1351 vs->features |= VNC_FEATURE_RESIZE_MASK;
1352 break;
1353 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1354 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1355 break;
1356 case VNC_ENCODING_EXT_KEY_EVENT:
9ca313aa
AL
1357 send_ext_key_event_ack(vs);
1358 break;
29fa4ed9 1359 case VNC_ENCODING_AUDIO:
429a8ed3 1360 send_ext_audio_ack(vs);
1361 break;
29fa4ed9
AL
1362 case VNC_ENCODING_WMVi:
1363 vs->features |= VNC_FEATURE_WMVI_MASK;
ca4cca4d 1364 break;
fb437313
AL
1365 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1366 vs->tight_compression = (enc & 0x0F);
1367 break;
1368 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1369 vs->tight_quality = (enc & 0x0F);
1370 break;
29fa4ed9
AL
1371 default:
1372 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1373 break;
1374 }
24236869 1375 }
564c337e
FB
1376
1377 check_pointer_type_change(vs, kbd_mouse_is_absolute());
24236869
FB
1378}
1379
6cec5487
AL
1380static void set_pixel_conversion(VncState *vs)
1381{
1382 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1383 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1384 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1385 vs->write_pixels = vnc_write_pixels_copy;
1386 switch (vs->ds->surface->pf.bits_per_pixel) {
1387 case 8:
1388 vs->send_hextile_tile = send_hextile_tile_8;
1389 break;
1390 case 16:
1391 vs->send_hextile_tile = send_hextile_tile_16;
1392 break;
1393 case 32:
1394 vs->send_hextile_tile = send_hextile_tile_32;
1395 break;
1396 }
1397 } else {
1398 vs->write_pixels = vnc_write_pixels_generic;
1399 switch (vs->ds->surface->pf.bits_per_pixel) {
1400 case 8:
1401 vs->send_hextile_tile = send_hextile_tile_generic_8;
1402 break;
1403 case 16:
1404 vs->send_hextile_tile = send_hextile_tile_generic_16;
1405 break;
1406 case 32:
1407 vs->send_hextile_tile = send_hextile_tile_generic_32;
1408 break;
1409 }
1410 }
1411}
1412
24236869
FB
1413static void set_pixel_format(VncState *vs,
1414 int bits_per_pixel, int depth,
1415 int big_endian_flag, int true_color_flag,
1416 int red_max, int green_max, int blue_max,
1417 int red_shift, int green_shift, int blue_shift)
1418{
3512779a 1419 if (!true_color_flag) {
24236869 1420 vnc_client_error(vs);
3512779a
FB
1421 return;
1422 }
24236869 1423
6cec5487
AL
1424 vs->clientds = vs->serverds;
1425 vs->clientds.pf.rmax = red_max;
90a1e3c0 1426 count_bits(vs->clientds.pf.rbits, red_max);
6cec5487
AL
1427 vs->clientds.pf.rshift = red_shift;
1428 vs->clientds.pf.rmask = red_max << red_shift;
1429 vs->clientds.pf.gmax = green_max;
90a1e3c0 1430 count_bits(vs->clientds.pf.gbits, green_max);
6cec5487
AL
1431 vs->clientds.pf.gshift = green_shift;
1432 vs->clientds.pf.gmask = green_max << green_shift;
1433 vs->clientds.pf.bmax = blue_max;
90a1e3c0 1434 count_bits(vs->clientds.pf.bbits, blue_max);
6cec5487
AL
1435 vs->clientds.pf.bshift = blue_shift;
1436 vs->clientds.pf.bmask = blue_max << blue_shift;
1437 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1438 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1439 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1440 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1441
1442 set_pixel_conversion(vs);
24236869
FB
1443
1444 vga_hw_invalidate();
1445 vga_hw_update();
1446}
1447
ca4cca4d
AL
1448static void pixel_format_message (VncState *vs) {
1449 char pad[3] = { 0, 0, 0 };
1450
6cec5487
AL
1451 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1452 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
ca4cca4d
AL
1453
1454#ifdef WORDS_BIGENDIAN
1455 vnc_write_u8(vs, 1); /* big-endian-flag */
1456#else
1457 vnc_write_u8(vs, 0); /* big-endian-flag */
1458#endif
1459 vnc_write_u8(vs, 1); /* true-color-flag */
6cec5487
AL
1460 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1461 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1462 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1463 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1464 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1465 vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
1466 if (vs->ds->surface->pf.bits_per_pixel == 32)
ca4cca4d 1467 vs->send_hextile_tile = send_hextile_tile_32;
6cec5487 1468 else if (vs->ds->surface->pf.bits_per_pixel == 16)
ca4cca4d 1469 vs->send_hextile_tile = send_hextile_tile_16;
6cec5487 1470 else if (vs->ds->surface->pf.bits_per_pixel == 8)
ca4cca4d 1471 vs->send_hextile_tile = send_hextile_tile_8;
6cec5487
AL
1472 vs->clientds = *(vs->ds->surface);
1473 vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
ca4cca4d
AL
1474 vs->write_pixels = vnc_write_pixels_copy;
1475
1476 vnc_write(vs, pad, 3); /* padding */
1477}
1478
7d957bd8
AL
1479static void vnc_dpy_setdata(DisplayState *ds)
1480{
1481 /* We don't have to do anything */
1482}
1483
753b4053 1484static void vnc_colordepth(VncState *vs)
7eac3a87 1485{
753b4053 1486 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
ca4cca4d
AL
1487 /* Sending a WMVi message to notify the client*/
1488 vnc_write_u8(vs, 0); /* msg id */
1489 vnc_write_u8(vs, 0);
1490 vnc_write_u16(vs, 1); /* number of rects */
753b4053
AL
1491 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
1492 ds_get_height(vs->ds), VNC_ENCODING_WMVi);
ca4cca4d
AL
1493 pixel_format_message(vs);
1494 vnc_flush(vs);
7eac3a87 1495 } else {
6cec5487 1496 set_pixel_conversion(vs);
7eac3a87
AL
1497 }
1498}
1499
60fe76f3 1500static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
24236869
FB
1501{
1502 int i;
1503 uint16_t limit;
1504
1505 switch (data[0]) {
1506 case 0:
1507 if (len == 1)
1508 return 20;
1509
1510 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1511 read_u8(data, 6), read_u8(data, 7),
1512 read_u16(data, 8), read_u16(data, 10),
1513 read_u16(data, 12), read_u8(data, 14),
1514 read_u8(data, 15), read_u8(data, 16));
1515 break;
1516 case 2:
1517 if (len == 1)
1518 return 4;
1519
69dd5c9f
AL
1520 if (len == 4) {
1521 limit = read_u16(data, 2);
1522 if (limit > 0)
1523 return 4 + (limit * 4);
1524 } else
1525 limit = read_u16(data, 2);
24236869 1526
24236869
FB
1527 for (i = 0; i < limit; i++) {
1528 int32_t val = read_s32(data, 4 + (i * 4));
1529 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1530 }
1531
1532 set_encodings(vs, (int32_t *)(data + 4), limit);
1533 break;
1534 case 3:
1535 if (len == 1)
1536 return 10;
1537
1538 framebuffer_update_request(vs,
1539 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1540 read_u16(data, 6), read_u16(data, 8));
1541 break;
1542 case 4:
1543 if (len == 1)
1544 return 8;
1545
1546 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1547 break;
1548 case 5:
1549 if (len == 1)
1550 return 6;
1551
1552 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1553 break;
1554 case 6:
1555 if (len == 1)
1556 return 8;
1557
baa7666c
TS
1558 if (len == 8) {
1559 uint32_t dlen = read_u32(data, 4);
1560 if (dlen > 0)
1561 return 8 + dlen;
1562 }
24236869
FB
1563
1564 client_cut_text(vs, read_u32(data, 4), data + 8);
1565 break;
9ca313aa
AL
1566 case 255:
1567 if (len == 1)
1568 return 2;
1569
1570 switch (read_u8(data, 1)) {
1571 case 0:
1572 if (len == 2)
1573 return 12;
1574
1575 ext_key_event(vs, read_u16(data, 2),
1576 read_u32(data, 4), read_u32(data, 8));
1577 break;
429a8ed3 1578 case 1:
1579 if (len == 2)
1580 return 4;
1581
1582 switch (read_u16 (data, 2)) {
1583 case 0:
1584 audio_add(vs);
1585 break;
1586 case 1:
1587 audio_del(vs);
1588 break;
1589 case 2:
1590 if (len == 4)
1591 return 10;
1592 switch (read_u8(data, 4)) {
1593 case 0: vs->as.fmt = AUD_FMT_U8; break;
1594 case 1: vs->as.fmt = AUD_FMT_S8; break;
1595 case 2: vs->as.fmt = AUD_FMT_U16; break;
1596 case 3: vs->as.fmt = AUD_FMT_S16; break;
1597 case 4: vs->as.fmt = AUD_FMT_U32; break;
1598 case 5: vs->as.fmt = AUD_FMT_S32; break;
1599 default:
1600 printf("Invalid audio format %d\n", read_u8(data, 4));
1601 vnc_client_error(vs);
1602 break;
1603 }
1604 vs->as.nchannels = read_u8(data, 5);
1605 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
1606 printf("Invalid audio channel coount %d\n",
1607 read_u8(data, 5));
1608 vnc_client_error(vs);
1609 break;
1610 }
1611 vs->as.freq = read_u32(data, 6);
1612 break;
1613 default:
1614 printf ("Invalid audio message %d\n", read_u8(data, 4));
1615 vnc_client_error(vs);
1616 break;
1617 }
1618 break;
1619
9ca313aa
AL
1620 default:
1621 printf("Msg: %d\n", read_u16(data, 0));
1622 vnc_client_error(vs);
1623 break;
1624 }
1625 break;
24236869
FB
1626 default:
1627 printf("Msg: %d\n", data[0]);
1628 vnc_client_error(vs);
1629 break;
1630 }
5fafdf24 1631
24236869
FB
1632 vnc_read_when(vs, protocol_client_msg, 1);
1633 return 0;
1634}
1635
60fe76f3 1636static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
24236869 1637{
c35734b2
TS
1638 char buf[1024];
1639 int size;
24236869 1640
0e1f5a0c
AL
1641 vnc_write_u16(vs, ds_get_width(vs->ds));
1642 vnc_write_u16(vs, ds_get_height(vs->ds));
24236869 1643
ca4cca4d 1644 pixel_format_message(vs);
24236869 1645
c35734b2
TS
1646 if (qemu_name)
1647 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1648 else
1649 size = snprintf(buf, sizeof(buf), "QEMU");
1650
1651 vnc_write_u32(vs, size);
1652 vnc_write(vs, buf, size);
24236869
FB
1653 vnc_flush(vs);
1654
1655 vnc_read_when(vs, protocol_client_msg, 1);
1656
1657 return 0;
1658}
1659
70848515
TS
1660static void make_challenge(VncState *vs)
1661{
1662 int i;
1663
1664 srand(time(NULL)+getpid()+getpid()*987654+rand());
1665
1666 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1667 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1668}
1669
60fe76f3 1670static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
70848515 1671{
60fe76f3 1672 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
70848515 1673 int i, j, pwlen;
60fe76f3 1674 unsigned char key[8];
70848515 1675
753b4053 1676 if (!vs->vd->password || !vs->vd->password[0]) {
70848515
TS
1677 VNC_DEBUG("No password configured on server");
1678 vnc_write_u32(vs, 1); /* Reject auth */
1679 if (vs->minor >= 8) {
1680 static const char err[] = "Authentication failed";
1681 vnc_write_u32(vs, sizeof(err));
1682 vnc_write(vs, err, sizeof(err));
1683 }
1684 vnc_flush(vs);
1685 vnc_client_error(vs);
1686 return 0;
1687 }
1688
1689 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1690
1691 /* Calculate the expected challenge response */
753b4053 1692 pwlen = strlen(vs->vd->password);
70848515 1693 for (i=0; i<sizeof(key); i++)
753b4053 1694 key[i] = i<pwlen ? vs->vd->password[i] : 0;
70848515
TS
1695 deskey(key, EN0);
1696 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1697 des(response+j, response+j);
1698
1699 /* Compare expected vs actual challenge response */
1700 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1701 VNC_DEBUG("Client challenge reponse did not match\n");
1702 vnc_write_u32(vs, 1); /* Reject auth */
1703 if (vs->minor >= 8) {
1704 static const char err[] = "Authentication failed";
1705 vnc_write_u32(vs, sizeof(err));
1706 vnc_write(vs, err, sizeof(err));
1707 }
1708 vnc_flush(vs);
1709 vnc_client_error(vs);
1710 } else {
1711 VNC_DEBUG("Accepting VNC challenge response\n");
1712 vnc_write_u32(vs, 0); /* Accept auth */
1713 vnc_flush(vs);
1714
1715 vnc_read_when(vs, protocol_client_init, 1);
1716 }
1717 return 0;
1718}
1719
1720static int start_auth_vnc(VncState *vs)
1721{
1722 make_challenge(vs);
1723 /* Send client a 'random' challenge */
1724 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1725 vnc_flush(vs);
1726
1727 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1728 return 0;
1729}
1730
8d5d2d4c 1731
eb38c52c 1732#ifdef CONFIG_VNC_TLS
8d5d2d4c
TS
1733#define DH_BITS 1024
1734static gnutls_dh_params_t dh_params;
1735
1736static int vnc_tls_initialize(void)
1737{
1738 static int tlsinitialized = 0;
1739
1740 if (tlsinitialized)
1741 return 1;
1742
1743 if (gnutls_global_init () < 0)
1744 return 0;
1745
1746 /* XXX ought to re-generate diffie-hellmen params periodically */
1747 if (gnutls_dh_params_init (&dh_params) < 0)
1748 return 0;
1749 if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
1750 return 0;
1751
234c9bcd 1752#if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
8d5d2d4c
TS
1753 gnutls_global_set_log_level(10);
1754 gnutls_global_set_log_function(vnc_debug_gnutls_log);
1755#endif
1756
1757 tlsinitialized = 1;
1758
1759 return 1;
1760}
1761
1762static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
1763{
1764 gnutls_anon_server_credentials anon_cred;
1765 int ret;
1766
1767 if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
1768 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1769 return NULL;
1770 }
1771
1772 gnutls_anon_set_server_dh_params(anon_cred, dh_params);
1773
1774 return anon_cred;
1775}
1776
1777
6f43024c 1778static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncState *vs)
3a702699
TS
1779{
1780 gnutls_certificate_credentials_t x509_cred;
1781 int ret;
6f43024c 1782
753b4053 1783 if (!vs->vd->x509cacert) {
6f43024c
TS
1784 VNC_DEBUG("No CA x509 certificate specified\n");
1785 return NULL;
1786 }
753b4053 1787 if (!vs->vd->x509cert) {
6f43024c
TS
1788 VNC_DEBUG("No server x509 certificate specified\n");
1789 return NULL;
1790 }
753b4053 1791 if (!vs->vd->x509key) {
6f43024c
TS
1792 VNC_DEBUG("No server private key specified\n");
1793 return NULL;
1794 }
3a702699
TS
1795
1796 if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
1797 VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
1798 return NULL;
1799 }
6f43024c 1800 if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
753b4053 1801 vs->vd->x509cacert,
6f43024c 1802 GNUTLS_X509_FMT_PEM)) < 0) {
3a702699
TS
1803 VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
1804 gnutls_certificate_free_credentials(x509_cred);
1805 return NULL;
1806 }
1807
6f43024c 1808 if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
753b4053
AL
1809 vs->vd->x509cert,
1810 vs->vd->x509key,
3a702699
TS
1811 GNUTLS_X509_FMT_PEM)) < 0) {
1812 VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
1813 gnutls_certificate_free_credentials(x509_cred);
1814 return NULL;
1815 }
1816
753b4053 1817 if (vs->vd->x509cacrl) {
6f43024c 1818 if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
753b4053 1819 vs->vd->x509cacrl,
6f43024c 1820 GNUTLS_X509_FMT_PEM)) < 0) {
3a702699
TS
1821 VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
1822 gnutls_certificate_free_credentials(x509_cred);
1823 return NULL;
1824 }
1825 }
1826
1827 gnutls_certificate_set_dh_params (x509_cred, dh_params);
1828
1829 return x509_cred;
1830}
1831
469b15c6
TS
1832static int vnc_validate_certificate(struct VncState *vs)
1833{
1834 int ret;
1835 unsigned int status;
1836 const gnutls_datum_t *certs;
1837 unsigned int nCerts, i;
1838 time_t now;
1839
1840 VNC_DEBUG("Validating client certificate\n");
1841 if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
1842 VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
1843 return -1;
1844 }
1845
1846 if ((now = time(NULL)) == ((time_t)-1)) {
1847 return -1;
1848 }
1849
1850 if (status != 0) {
1851 if (status & GNUTLS_CERT_INVALID)
1852 VNC_DEBUG("The certificate is not trusted.\n");
1853
1854 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
1855 VNC_DEBUG("The certificate hasn't got a known issuer.\n");
1856
1857 if (status & GNUTLS_CERT_REVOKED)
1858 VNC_DEBUG("The certificate has been revoked.\n");
1859
1860 if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
1861 VNC_DEBUG("The certificate uses an insecure algorithm\n");
1862
1863 return -1;
1864 } else {
1865 VNC_DEBUG("Certificate is valid!\n");
1866 }
1867
1868 /* Only support x509 for now */
1869 if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
1870 return -1;
1871
1872 if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
1873 return -1;
1874
1875 for (i = 0 ; i < nCerts ; i++) {
1876 gnutls_x509_crt_t cert;
1877 VNC_DEBUG ("Checking certificate chain %d\n", i);
1878 if (gnutls_x509_crt_init (&cert) < 0)
1879 return -1;
1880
1881 if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
1882 gnutls_x509_crt_deinit (cert);
1883 return -1;
1884 }
1885
1886 if (gnutls_x509_crt_get_expiration_time (cert) < now) {
1887 VNC_DEBUG("The certificate has expired\n");
1888 gnutls_x509_crt_deinit (cert);
1889 return -1;
1890 }
1891
1892 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1893 VNC_DEBUG("The certificate is not yet activated\n");
1894 gnutls_x509_crt_deinit (cert);
1895 return -1;
1896 }
1897
1898 if (gnutls_x509_crt_get_activation_time (cert) > now) {
1899 VNC_DEBUG("The certificate is not yet activated\n");
1900 gnutls_x509_crt_deinit (cert);
1901 return -1;
1902 }
1903
1904 gnutls_x509_crt_deinit (cert);
1905 }
1906
1907 return 0;
1908}
1909
1910
8d5d2d4c
TS
1911static int start_auth_vencrypt_subauth(VncState *vs)
1912{
753b4053 1913 switch (vs->vd->subauth) {
8d5d2d4c 1914 case VNC_AUTH_VENCRYPT_TLSNONE:
3a702699 1915 case VNC_AUTH_VENCRYPT_X509NONE:
8d5d2d4c
TS
1916 VNC_DEBUG("Accept TLS auth none\n");
1917 vnc_write_u32(vs, 0); /* Accept auth completion */
1918 vnc_read_when(vs, protocol_client_init, 1);
1919 break;
1920
1921 case VNC_AUTH_VENCRYPT_TLSVNC:
3a702699 1922 case VNC_AUTH_VENCRYPT_X509VNC:
8d5d2d4c
TS
1923 VNC_DEBUG("Start TLS auth VNC\n");
1924 return start_auth_vnc(vs);
1925
1926 default: /* Should not be possible, but just in case */
753b4053 1927 VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
8d5d2d4c
TS
1928 vnc_write_u8(vs, 1);
1929 if (vs->minor >= 8) {
1930 static const char err[] = "Unsupported authentication type";
1931 vnc_write_u32(vs, sizeof(err));
1932 vnc_write(vs, err, sizeof(err));
1933 }
1934 vnc_client_error(vs);
1935 }
1936
1937 return 0;
1938}
1939
1940static void vnc_handshake_io(void *opaque);
1941
1942static int vnc_continue_handshake(struct VncState *vs) {
1943 int ret;
1944
1945 if ((ret = gnutls_handshake(vs->tls_session)) < 0) {
1946 if (!gnutls_error_is_fatal(ret)) {
1947 VNC_DEBUG("Handshake interrupted (blocking)\n");
1948 if (!gnutls_record_get_direction(vs->tls_session))
1949 qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs);
1950 else
1951 qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs);
1952 return 0;
1953 }
1954 VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
1955 vnc_client_error(vs);
1956 return -1;
1957 }
1958
753b4053 1959 if (vs->vd->x509verify) {
469b15c6
TS
1960 if (vnc_validate_certificate(vs) < 0) {
1961 VNC_DEBUG("Client verification failed\n");
1962 vnc_client_error(vs);
1963 return -1;
1964 } else {
1965 VNC_DEBUG("Client verification passed\n");
1966 }
1967 }
1968
8d5d2d4c
TS
1969 VNC_DEBUG("Handshake done, switching to TLS data mode\n");
1970 vs->wiremode = VNC_WIREMODE_TLS;
1971 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1972
1973 return start_auth_vencrypt_subauth(vs);
1974}
1975
1976static void vnc_handshake_io(void *opaque) {
1977 struct VncState *vs = (struct VncState *)opaque;
1978
1979 VNC_DEBUG("Handshake IO continue\n");
1980 vnc_continue_handshake(vs);
1981}
1982
3a702699 1983#define NEED_X509_AUTH(vs) \
753b4053
AL
1984 ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
1985 (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
1986 (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN)
3a702699
TS
1987
1988
8d5d2d4c
TS
1989static int vnc_start_tls(struct VncState *vs) {
1990 static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
1991 static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
1992 static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
3a702699 1993 static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
8d5d2d4c
TS
1994
1995 VNC_DEBUG("Do TLS setup\n");
1996 if (vnc_tls_initialize() < 0) {
1997 VNC_DEBUG("Failed to init TLS\n");
1998 vnc_client_error(vs);
1999 return -1;
2000 }
2001 if (vs->tls_session == NULL) {
2002 if (gnutls_init(&vs->tls_session, GNUTLS_SERVER) < 0) {
2003 vnc_client_error(vs);
2004 return -1;
2005 }
2006
2007 if (gnutls_set_default_priority(vs->tls_session) < 0) {
2008 gnutls_deinit(vs->tls_session);
2009 vs->tls_session = NULL;
2010 vnc_client_error(vs);
2011 return -1;
2012 }
2013
3a702699 2014 if (gnutls_kx_set_priority(vs->tls_session, NEED_X509_AUTH(vs) ? kx_x509 : kx_anon) < 0) {
8d5d2d4c
TS
2015 gnutls_deinit(vs->tls_session);
2016 vs->tls_session = NULL;
2017 vnc_client_error(vs);
2018 return -1;
2019 }
2020
2021 if (gnutls_certificate_type_set_priority(vs->tls_session, cert_type_priority) < 0) {
2022 gnutls_deinit(vs->tls_session);
2023 vs->tls_session = NULL;
2024 vnc_client_error(vs);
2025 return -1;
2026 }
2027
2028 if (gnutls_protocol_set_priority(vs->tls_session, protocol_priority) < 0) {
2029 gnutls_deinit(vs->tls_session);
2030 vs->tls_session = NULL;
2031 vnc_client_error(vs);
2032 return -1;
2033 }
2034
3a702699 2035 if (NEED_X509_AUTH(vs)) {
6f43024c 2036 gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs);
3a702699
TS
2037 if (!x509_cred) {
2038 gnutls_deinit(vs->tls_session);
2039 vs->tls_session = NULL;
2040 vnc_client_error(vs);
2041 return -1;
2042 }
2043 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
2044 gnutls_deinit(vs->tls_session);
2045 vs->tls_session = NULL;
2046 gnutls_certificate_free_credentials(x509_cred);
2047 vnc_client_error(vs);
2048 return -1;
2049 }
753b4053 2050 if (vs->vd->x509verify) {
469b15c6
TS
2051 VNC_DEBUG("Requesting a client certificate\n");
2052 gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
2053 }
2054
3a702699
TS
2055 } else {
2056 gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
2057 if (!anon_cred) {
2058 gnutls_deinit(vs->tls_session);
2059 vs->tls_session = NULL;
2060 vnc_client_error(vs);
2061 return -1;
2062 }
2063 if (gnutls_credentials_set(vs->tls_session, GNUTLS_CRD_ANON, anon_cred) < 0) {
2064 gnutls_deinit(vs->tls_session);
2065 vs->tls_session = NULL;
2066 gnutls_anon_free_server_credentials(anon_cred);
2067 vnc_client_error(vs);
2068 return -1;
2069 }
8d5d2d4c
TS
2070 }
2071
2072 gnutls_transport_set_ptr(vs->tls_session, (gnutls_transport_ptr_t)vs);
2073 gnutls_transport_set_push_function(vs->tls_session, vnc_tls_push);
2074 gnutls_transport_set_pull_function(vs->tls_session, vnc_tls_pull);
2075 }
2076
2077 VNC_DEBUG("Start TLS handshake process\n");
2078 return vnc_continue_handshake(vs);
2079}
2080
60fe76f3 2081static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
8d5d2d4c
TS
2082{
2083 int auth = read_u32(data, 0);
2084
753b4053 2085 if (auth != vs->vd->subauth) {
8d5d2d4c
TS
2086 VNC_DEBUG("Rejecting auth %d\n", auth);
2087 vnc_write_u8(vs, 0); /* Reject auth */
2088 vnc_flush(vs);
2089 vnc_client_error(vs);
2090 } else {
2091 VNC_DEBUG("Accepting auth %d, starting handshake\n", auth);
2092 vnc_write_u8(vs, 1); /* Accept auth */
2093 vnc_flush(vs);
2094
2095 if (vnc_start_tls(vs) < 0) {
2096 VNC_DEBUG("Failed to complete TLS\n");
2097 return 0;
2098 }
2099
2100 if (vs->wiremode == VNC_WIREMODE_TLS) {
2101 VNC_DEBUG("Starting VeNCrypt subauth\n");
2102 return start_auth_vencrypt_subauth(vs);
2103 } else {
2104 VNC_DEBUG("TLS handshake blocked\n");
2105 return 0;
2106 }
2107 }
2108 return 0;
2109}
2110
60fe76f3 2111static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
8d5d2d4c
TS
2112{
2113 if (data[0] != 0 ||
2114 data[1] != 2) {
2115 VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
2116 vnc_write_u8(vs, 1); /* Reject version */
2117 vnc_flush(vs);
2118 vnc_client_error(vs);
2119 } else {
753b4053 2120 VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);
8d5d2d4c
TS
2121 vnc_write_u8(vs, 0); /* Accept version */
2122 vnc_write_u8(vs, 1); /* Number of sub-auths */
753b4053 2123 vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */
8d5d2d4c
TS
2124 vnc_flush(vs);
2125 vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
2126 }
2127 return 0;
2128}
2129
2130static int start_auth_vencrypt(VncState *vs)
2131{
2132 /* Send VeNCrypt version 0.2 */
2133 vnc_write_u8(vs, 0);
2134 vnc_write_u8(vs, 2);
2135
2136 vnc_read_when(vs, protocol_client_vencrypt_init, 2);
2137 return 0;
2138}
2139#endif /* CONFIG_VNC_TLS */
2140
60fe76f3 2141static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
70848515
TS
2142{
2143 /* We only advertise 1 auth scheme at a time, so client
2144 * must pick the one we sent. Verify this */
753b4053 2145 if (data[0] != vs->vd->auth) { /* Reject auth */
70848515
TS
2146 VNC_DEBUG("Reject auth %d\n", (int)data[0]);
2147 vnc_write_u32(vs, 1);
2148 if (vs->minor >= 8) {
2149 static const char err[] = "Authentication failed";
2150 vnc_write_u32(vs, sizeof(err));
2151 vnc_write(vs, err, sizeof(err));
2152 }
2153 vnc_client_error(vs);
2154 } else { /* Accept requested auth */
2155 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
753b4053 2156 switch (vs->vd->auth) {
70848515
TS
2157 case VNC_AUTH_NONE:
2158 VNC_DEBUG("Accept auth none\n");
a26c97ad
AZ
2159 if (vs->minor >= 8) {
2160 vnc_write_u32(vs, 0); /* Accept auth completion */
2161 vnc_flush(vs);
2162 }
70848515
TS
2163 vnc_read_when(vs, protocol_client_init, 1);
2164 break;
2165
2166 case VNC_AUTH_VNC:
2167 VNC_DEBUG("Start VNC auth\n");
2168 return start_auth_vnc(vs);
2169
eb38c52c 2170#ifdef CONFIG_VNC_TLS
8d5d2d4c
TS
2171 case VNC_AUTH_VENCRYPT:
2172 VNC_DEBUG("Accept VeNCrypt auth\n");;
2173 return start_auth_vencrypt(vs);
2174#endif /* CONFIG_VNC_TLS */
2175
70848515 2176 default: /* Should not be possible, but just in case */
753b4053 2177 VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
70848515
TS
2178 vnc_write_u8(vs, 1);
2179 if (vs->minor >= 8) {
2180 static const char err[] = "Authentication failed";
2181 vnc_write_u32(vs, sizeof(err));
2182 vnc_write(vs, err, sizeof(err));
2183 }
2184 vnc_client_error(vs);
2185 }
2186 }
2187 return 0;
2188}
2189
60fe76f3 2190static int protocol_version(VncState *vs, uint8_t *version, size_t len)
24236869
FB
2191{
2192 char local[13];
24236869
FB
2193
2194 memcpy(local, version, 12);
2195 local[12] = 0;
2196
70848515
TS
2197 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2198 VNC_DEBUG("Malformed protocol version %s\n", local);
24236869
FB
2199 vnc_client_error(vs);
2200 return 0;
2201 }
70848515
TS
2202 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2203 if (vs->major != 3 ||
2204 (vs->minor != 3 &&
b0566f4f 2205 vs->minor != 4 &&
70848515
TS
2206 vs->minor != 5 &&
2207 vs->minor != 7 &&
2208 vs->minor != 8)) {
2209 VNC_DEBUG("Unsupported client version\n");
2210 vnc_write_u32(vs, VNC_AUTH_INVALID);
2211 vnc_flush(vs);
2212 vnc_client_error(vs);
2213 return 0;
2214 }
b0566f4f 2215 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
70848515
TS
2216 * as equivalent to v3.3 by servers
2217 */
b0566f4f 2218 if (vs->minor == 4 || vs->minor == 5)
70848515
TS
2219 vs->minor = 3;
2220
2221 if (vs->minor == 3) {
753b4053 2222 if (vs->vd->auth == VNC_AUTH_NONE) {
70848515 2223 VNC_DEBUG("Tell client auth none\n");
753b4053 2224 vnc_write_u32(vs, vs->vd->auth);
70848515
TS
2225 vnc_flush(vs);
2226 vnc_read_when(vs, protocol_client_init, 1);
753b4053 2227 } else if (vs->vd->auth == VNC_AUTH_VNC) {
70848515 2228 VNC_DEBUG("Tell client VNC auth\n");
753b4053 2229 vnc_write_u32(vs, vs->vd->auth);
70848515
TS
2230 vnc_flush(vs);
2231 start_auth_vnc(vs);
2232 } else {
753b4053 2233 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
70848515
TS
2234 vnc_write_u32(vs, VNC_AUTH_INVALID);
2235 vnc_flush(vs);
2236 vnc_client_error(vs);
2237 }
2238 } else {
753b4053 2239 VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
70848515 2240 vnc_write_u8(vs, 1); /* num auth */
753b4053 2241 vnc_write_u8(vs, vs->vd->auth);
70848515
TS
2242 vnc_read_when(vs, protocol_client_auth, 1);
2243 vnc_flush(vs);
2244 }
24236869
FB
2245
2246 return 0;
2247}
2248
753b4053 2249static void vnc_connect(VncDisplay *vd, int csock)
3aa3eea3 2250{
753b4053
AL
2251 VncState *vs = qemu_mallocz(sizeof(VncState));
2252 vs->csock = csock;
2253
2254 VNC_DEBUG("New client on socket %d\n", csock);
7d957bd8 2255 dcl->idle = 0;
3aa3eea3
AZ
2256 socket_set_nonblock(vs->csock);
2257 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
753b4053
AL
2258
2259 vs->vd = vd;
2260 vs->ds = vd->ds;
2261 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
2262 vs->last_x = -1;
2263 vs->last_y = -1;
2264
2265 vs->as.freq = 44100;
2266 vs->as.nchannels = 2;
2267 vs->as.fmt = AUD_FMT_S16;
2268 vs->as.endianness = 0;
2269
2270 vnc_resize(vs);
3aa3eea3
AZ
2271 vnc_write(vs, "RFB 003.008\n", 12);
2272 vnc_flush(vs);
2273 vnc_read_when(vs, protocol_version, 12);
0e1f5a0c 2274 memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
3aa3eea3 2275 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
3aa3eea3 2276 vnc_update_client(vs);
53762ddb 2277 reset_keys(vs);
753b4053
AL
2278
2279 vs->next = vd->clients;
2280 vd->clients = vs;
3aa3eea3
AZ
2281}
2282
24236869
FB
2283static void vnc_listen_read(void *opaque)
2284{
753b4053 2285 VncDisplay *vs = opaque;
24236869
FB
2286 struct sockaddr_in addr;
2287 socklen_t addrlen = sizeof(addr);
2288
9f60ad50
AZ
2289 /* Catch-up */
2290 vga_hw_update();
2291
753b4053
AL
2292 int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2293 if (csock != -1) {
2294 vnc_connect(vs, csock);
24236869
FB
2295 }
2296}
2297
71cab5ca 2298void vnc_display_init(DisplayState *ds)
24236869 2299{
753b4053 2300 VncDisplay *vs;
24236869
FB
2301
2302 vs = qemu_mallocz(sizeof(VncState));
7d957bd8 2303 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
24236869
FB
2304
2305 ds->opaque = vs;
7d957bd8 2306 dcl->idle = 1;
753b4053 2307 vnc_display = vs;
24236869
FB
2308
2309 vs->lsock = -1;
24236869
FB
2310
2311 vs->ds = ds;
2312
9ca313aa
AL
2313 if (keyboard_layout)
2314 vs->kbd_layout = init_keyboard_layout(keyboard_layout);
2315 else
2316 vs->kbd_layout = init_keyboard_layout("en-us");
24236869 2317
24236869
FB
2318 if (!vs->kbd_layout)
2319 exit(1);
2320
753b4053 2321 dcl->dpy_copy = vnc_dpy_copy;
7d957bd8
AL
2322 dcl->dpy_update = vnc_dpy_update;
2323 dcl->dpy_resize = vnc_dpy_resize;
2324 dcl->dpy_setdata = vnc_dpy_setdata;
7d957bd8 2325 register_displaychangelistener(ds, dcl);
71cab5ca
TS
2326}
2327
eb38c52c 2328#ifdef CONFIG_VNC_TLS
753b4053 2329static int vnc_set_x509_credential(VncDisplay *vs,
6f43024c
TS
2330 const char *certdir,
2331 const char *filename,
2332 char **cred,
2333 int ignoreMissing)
2334{
2335 struct stat sb;
2336
2337 if (*cred) {
2338 qemu_free(*cred);
2339 *cred = NULL;
2340 }
2341
1eec614b 2342 *cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2);
6f43024c
TS
2343
2344 strcpy(*cred, certdir);
2345 strcat(*cred, "/");
2346 strcat(*cred, filename);
2347
2348 VNC_DEBUG("Check %s\n", *cred);
2349 if (stat(*cred, &sb) < 0) {
2350 qemu_free(*cred);
2351 *cred = NULL;
2352 if (ignoreMissing && errno == ENOENT)
2353 return 0;
2354 return -1;
2355 }
2356
2357 return 0;
2358}
2359
753b4053 2360static int vnc_set_x509_credential_dir(VncDisplay *vs,
6f43024c
TS
2361 const char *certdir)
2362{
2363 if (vnc_set_x509_credential(vs, certdir, X509_CA_CERT_FILE, &vs->x509cacert, 0) < 0)
2364 goto cleanup;
2365 if (vnc_set_x509_credential(vs, certdir, X509_CA_CRL_FILE, &vs->x509cacrl, 1) < 0)
2366 goto cleanup;
2367 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_CERT_FILE, &vs->x509cert, 0) < 0)
2368 goto cleanup;
2369 if (vnc_set_x509_credential(vs, certdir, X509_SERVER_KEY_FILE, &vs->x509key, 0) < 0)
2370 goto cleanup;
2371
2372 return 0;
2373
2374 cleanup:
2375 qemu_free(vs->x509cacert);
2376 qemu_free(vs->x509cacrl);
2377 qemu_free(vs->x509cert);
2378 qemu_free(vs->x509key);
2379 vs->x509cacert = vs->x509cacrl = vs->x509cert = vs->x509key = NULL;
2380 return -1;
2381}
2382#endif /* CONFIG_VNC_TLS */
2383
71cab5ca
TS
2384void vnc_display_close(DisplayState *ds)
2385{
753b4053 2386 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
71cab5ca 2387
452b4d88
AL
2388 if (!vs)
2389 return;
71cab5ca
TS
2390 if (vs->display) {
2391 qemu_free(vs->display);
2392 vs->display = NULL;
2393 }
2394 if (vs->lsock != -1) {
2395 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2396 close(vs->lsock);
2397 vs->lsock = -1;
2398 }
70848515 2399 vs->auth = VNC_AUTH_INVALID;
eb38c52c 2400#ifdef CONFIG_VNC_TLS
8d5d2d4c 2401 vs->subauth = VNC_AUTH_INVALID;
469b15c6 2402 vs->x509verify = 0;
8d5d2d4c 2403#endif
70848515
TS
2404}
2405
2406int vnc_display_password(DisplayState *ds, const char *password)
2407{
753b4053 2408 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
70848515
TS
2409
2410 if (vs->password) {
2411 qemu_free(vs->password);
2412 vs->password = NULL;
2413 }
2414 if (password && password[0]) {
2415 if (!(vs->password = qemu_strdup(password)))
2416 return -1;
2417 }
2418
2419 return 0;
71cab5ca
TS
2420}
2421
70848515 2422int vnc_display_open(DisplayState *ds, const char *display)
71cab5ca 2423{
753b4053 2424 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
70848515
TS
2425 const char *options;
2426 int password = 0;
3aa3eea3 2427 int reverse = 0;
9712ecaf 2428 int to_port = 0;
eb38c52c 2429#ifdef CONFIG_VNC_TLS
3a702699 2430 int tls = 0, x509 = 0;
8d5d2d4c 2431#endif
71cab5ca 2432
753b4053 2433 if (!vnc_display)
452b4d88 2434 return -1;
71cab5ca 2435 vnc_display_close(ds);
70848515 2436 if (strcmp(display, "none") == 0)
71cab5ca 2437 return 0;
24236869 2438
70848515 2439 if (!(vs->display = strdup(display)))
71cab5ca 2440 return -1;
70848515
TS
2441
2442 options = display;
2443 while ((options = strchr(options, ','))) {
2444 options++;
469b15c6 2445 if (strncmp(options, "password", 8) == 0) {
70848515 2446 password = 1; /* Require password auth */
3aa3eea3
AZ
2447 } else if (strncmp(options, "reverse", 7) == 0) {
2448 reverse = 1;
9712ecaf
AL
2449 } else if (strncmp(options, "to=", 3) == 0) {
2450 to_port = atoi(options+3) + 5900;
eb38c52c 2451#ifdef CONFIG_VNC_TLS
469b15c6 2452 } else if (strncmp(options, "tls", 3) == 0) {
8d5d2d4c 2453 tls = 1; /* Require TLS */
469b15c6 2454 } else if (strncmp(options, "x509", 4) == 0) {
6f43024c 2455 char *start, *end;
3a702699 2456 x509 = 1; /* Require x509 certificates */
6f43024c
TS
2457 if (strncmp(options, "x509verify", 10) == 0)
2458 vs->x509verify = 1; /* ...and verify client certs */
2459
2460 /* Now check for 'x509=/some/path' postfix
2461 * and use that to setup x509 certificate/key paths */
2462 start = strchr(options, '=');
2463 end = strchr(options, ',');
2464 if (start && (!end || (start < end))) {
2465 int len = end ? end-(start+1) : strlen(start+1);
be351261 2466 char *path = qemu_strndup(start + 1, len);
be15b141 2467
6f43024c
TS
2468 VNC_DEBUG("Trying certificate path '%s'\n", path);
2469 if (vnc_set_x509_credential_dir(vs, path) < 0) {
2470 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2471 qemu_free(path);
2472 qemu_free(vs->display);
2473 vs->display = NULL;
2474 return -1;
2475 }
2476 qemu_free(path);
2477 } else {
2478 fprintf(stderr, "No certificate path provided\n");
2479 qemu_free(vs->display);
2480 vs->display = NULL;
2481 return -1;
2482 }
8d5d2d4c 2483#endif
469b15c6 2484 }
70848515
TS
2485 }
2486
2487 if (password) {
eb38c52c 2488#ifdef CONFIG_VNC_TLS
8d5d2d4c 2489 if (tls) {
8d5d2d4c 2490 vs->auth = VNC_AUTH_VENCRYPT;
3a702699
TS
2491 if (x509) {
2492 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2493 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2494 } else {
2495 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2496 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2497 }
8d5d2d4c
TS
2498 } else {
2499#endif
2500 VNC_DEBUG("Initializing VNC server with password auth\n");
2501 vs->auth = VNC_AUTH_VNC;
eb38c52c 2502#ifdef CONFIG_VNC_TLS
8d5d2d4c
TS
2503 vs->subauth = VNC_AUTH_INVALID;
2504 }
2505#endif
70848515 2506 } else {
eb38c52c 2507#ifdef CONFIG_VNC_TLS
8d5d2d4c 2508 if (tls) {
8d5d2d4c 2509 vs->auth = VNC_AUTH_VENCRYPT;
3a702699
TS
2510 if (x509) {
2511 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2512 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2513 } else {
2514 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2515 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2516 }
8d5d2d4c
TS
2517 } else {
2518#endif
2519 VNC_DEBUG("Initializing VNC server with no auth\n");
2520 vs->auth = VNC_AUTH_NONE;
eb38c52c 2521#ifdef CONFIG_VNC_TLS
8d5d2d4c
TS
2522 vs->subauth = VNC_AUTH_INVALID;
2523 }
2524#endif
70848515 2525 }
24236869 2526
3aa3eea3 2527 if (reverse) {
9712ecaf
AL
2528 /* connect to viewer */
2529 if (strncmp(display, "unix:", 5) == 0)
2530 vs->lsock = unix_connect(display+5);
2531 else
2532 vs->lsock = inet_connect(display, SOCK_STREAM);
2533 if (-1 == vs->lsock) {
3aa3eea3
AZ
2534 free(vs->display);
2535 vs->display = NULL;
2536 return -1;
2537 } else {
753b4053 2538 int csock = vs->lsock;
3aa3eea3 2539 vs->lsock = -1;
753b4053 2540 vnc_connect(vs, csock);
3aa3eea3 2541 }
9712ecaf 2542 return 0;
24236869 2543
9712ecaf
AL
2544 } else {
2545 /* listen for connects */
2546 char *dpy;
2547 dpy = qemu_malloc(256);
2548 if (strncmp(display, "unix:", 5) == 0) {
bc575e95 2549 pstrcpy(dpy, 256, "unix:");
4a55bfdf 2550 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
9712ecaf
AL
2551 } else {
2552 vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
2553 }
2554 if (-1 == vs->lsock) {
2555 free(dpy);
d0513623 2556 return -1;
9712ecaf
AL
2557 } else {
2558 free(vs->display);
2559 vs->display = dpy;
2560 }
24236869 2561 }
753b4053 2562 return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);
24236869 2563}