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