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