target-ppc: fix cpu_clone_regs
[qemu/aliguori-queue.git] / vnc.c
blob903dd953d9a434cdc2ab7c4cab485f989d471f3d
1 /*
2 * QEMU VNC display driver
4 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
5 * Copyright (C) 2006 Fabrice Bellard
6 * Copyright (C) 2009 Red Hat, Inc
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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.
27 #include "vnc.h"
28 #include "sysemu.h"
29 #include "qemu_socket.h"
30 #include "qemu-timer.h"
31 #include "acl.h"
33 #define VNC_REFRESH_INTERVAL (1000 / 30)
35 #include "vnc_keysym.h"
36 #include "d3des.h"
38 #define count_bits(c, v) { \
39 for (c = 0; v; v >>= 1) \
40 { \
41 c += v & 1; \
42 } \
46 static VncDisplay *vnc_display; /* needed for info vnc */
47 static DisplayChangeListener *dcl;
49 static char *addr_to_string(const char *format,
50 struct sockaddr_storage *sa,
51 socklen_t salen) {
52 char *addr;
53 char host[NI_MAXHOST];
54 char serv[NI_MAXSERV];
55 int err;
56 size_t addrlen;
58 if ((err = getnameinfo((struct sockaddr *)sa, salen,
59 host, sizeof(host),
60 serv, sizeof(serv),
61 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
62 VNC_DEBUG("Cannot resolve address %d: %s\n",
63 err, gai_strerror(err));
64 return NULL;
67 /* Enough for the existing format + the 2 vars we're
68 * substituting in. */
69 addrlen = strlen(format) + strlen(host) + strlen(serv);
70 addr = qemu_malloc(addrlen + 1);
71 snprintf(addr, addrlen, format, host, serv);
72 addr[addrlen] = '\0';
74 return addr;
78 char *vnc_socket_local_addr(const char *format, int fd) {
79 struct sockaddr_storage sa;
80 socklen_t salen;
82 salen = sizeof(sa);
83 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
84 return NULL;
86 return addr_to_string(format, &sa, salen);
89 char *vnc_socket_remote_addr(const char *format, int fd) {
90 struct sockaddr_storage sa;
91 socklen_t salen;
93 salen = sizeof(sa);
94 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
95 return NULL;
97 return addr_to_string(format, &sa, salen);
100 static const char *vnc_auth_name(VncDisplay *vd) {
101 switch (vd->auth) {
102 case VNC_AUTH_INVALID:
103 return "invalid";
104 case VNC_AUTH_NONE:
105 return "none";
106 case VNC_AUTH_VNC:
107 return "vnc";
108 case VNC_AUTH_RA2:
109 return "ra2";
110 case VNC_AUTH_RA2NE:
111 return "ra2ne";
112 case VNC_AUTH_TIGHT:
113 return "tight";
114 case VNC_AUTH_ULTRA:
115 return "ultra";
116 case VNC_AUTH_TLS:
117 return "tls";
118 case VNC_AUTH_VENCRYPT:
119 #ifdef CONFIG_VNC_TLS
120 switch (vd->subauth) {
121 case VNC_AUTH_VENCRYPT_PLAIN:
122 return "vencrypt+plain";
123 case VNC_AUTH_VENCRYPT_TLSNONE:
124 return "vencrypt+tls+none";
125 case VNC_AUTH_VENCRYPT_TLSVNC:
126 return "vencrypt+tls+vnc";
127 case VNC_AUTH_VENCRYPT_TLSPLAIN:
128 return "vencrypt+tls+plain";
129 case VNC_AUTH_VENCRYPT_X509NONE:
130 return "vencrypt+x509+none";
131 case VNC_AUTH_VENCRYPT_X509VNC:
132 return "vencrypt+x509+vnc";
133 case VNC_AUTH_VENCRYPT_X509PLAIN:
134 return "vencrypt+x509+plain";
135 case VNC_AUTH_VENCRYPT_TLSSASL:
136 return "vencrypt+tls+sasl";
137 case VNC_AUTH_VENCRYPT_X509SASL:
138 return "vencrypt+x509+sasl";
139 default:
140 return "vencrypt";
142 #else
143 return "vencrypt";
144 #endif
145 case VNC_AUTH_SASL:
146 return "sasl";
148 return "unknown";
151 static void do_info_vnc_client(Monitor *mon, VncState *client)
153 char *clientAddr =
154 vnc_socket_remote_addr(" address: %s:%s\n",
155 client->csock);
156 if (!clientAddr)
157 return;
159 monitor_printf(mon, "Client:\n");
160 monitor_printf(mon, "%s", clientAddr);
161 free(clientAddr);
163 #ifdef CONFIG_VNC_TLS
164 if (client->tls.session &&
165 client->tls.dname)
166 monitor_printf(mon, " x509 dname: %s\n", client->tls.dname);
167 else
168 monitor_printf(mon, " x509 dname: none\n");
169 #endif
170 #ifdef CONFIG_VNC_SASL
171 if (client->sasl.conn &&
172 client->sasl.username)
173 monitor_printf(mon, " username: %s\n", client->sasl.username);
174 else
175 monitor_printf(mon, " username: none\n");
176 #endif
179 void do_info_vnc(Monitor *mon)
181 if (vnc_display == NULL || vnc_display->display == NULL) {
182 monitor_printf(mon, "Server: disabled\n");
183 } else {
184 char *serverAddr = vnc_socket_local_addr(" address: %s:%s\n",
185 vnc_display->lsock);
187 if (!serverAddr)
188 return;
190 monitor_printf(mon, "Server:\n");
191 monitor_printf(mon, "%s", serverAddr);
192 free(serverAddr);
193 monitor_printf(mon, " auth: %s\n", vnc_auth_name(vnc_display));
195 if (vnc_display->clients) {
196 VncState *client = vnc_display->clients;
197 while (client) {
198 do_info_vnc_client(mon, client);
199 client = client->next;
201 } else {
202 monitor_printf(mon, "Client: none\n");
207 static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
208 return (vs->features & (1 << feature));
211 /* TODO
212 1) Get the queue working for IO.
213 2) there is some weirdness when using the -S option (the screen is grey
214 and not totally invalidated
215 3) resolutions > 1024
218 static void vnc_update_client(void *opaque);
219 static void vnc_disconnect_start(VncState *vs);
220 static void vnc_disconnect_finish(VncState *vs);
222 static void vnc_colordepth(VncState *vs);
224 static inline void vnc_set_bit(uint32_t *d, int k)
226 d[k >> 5] |= 1 << (k & 0x1f);
229 static inline void vnc_clear_bit(uint32_t *d, int k)
231 d[k >> 5] &= ~(1 << (k & 0x1f));
234 static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
236 int j;
238 j = 0;
239 while (n >= 32) {
240 d[j++] = -1;
241 n -= 32;
243 if (n > 0)
244 d[j++] = (1 << n) - 1;
245 while (j < nb_words)
246 d[j++] = 0;
249 static inline int vnc_get_bit(const uint32_t *d, int k)
251 return (d[k >> 5] >> (k & 0x1f)) & 1;
254 static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
255 int nb_words)
257 int i;
258 for(i = 0; i < nb_words; i++) {
259 if ((d1[i] & d2[i]) != 0)
260 return 1;
262 return 0;
265 static void vnc_update(VncState *vs, int x, int y, int w, int h)
267 struct VncSurface *s = &vs->guest;
268 int i;
270 h += y;
272 /* round x down to ensure the loop only spans one 16-pixel block per,
273 iteration. otherwise, if (x % 16) != 0, the last iteration may span
274 two 16-pixel blocks but we only mark the first as dirty
276 w += (x % 16);
277 x -= (x % 16);
279 x = MIN(x, s->ds->width);
280 y = MIN(y, s->ds->height);
281 w = MIN(x + w, s->ds->width) - x;
282 h = MIN(h, s->ds->height);
284 for (; y < h; y++)
285 for (i = 0; i < w; i += 16)
286 vnc_set_bit(s->dirty[y], (x + i) / 16);
289 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
291 VncDisplay *vd = ds->opaque;
292 VncState *vs = vd->clients;
293 while (vs != NULL) {
294 vnc_update(vs, x, y, w, h);
295 vs = vs->next;
299 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
300 int32_t encoding)
302 vnc_write_u16(vs, x);
303 vnc_write_u16(vs, y);
304 vnc_write_u16(vs, w);
305 vnc_write_u16(vs, h);
307 vnc_write_s32(vs, encoding);
310 void buffer_reserve(Buffer *buffer, size_t len)
312 if ((buffer->capacity - buffer->offset) < len) {
313 buffer->capacity += (len + 1024);
314 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
315 if (buffer->buffer == NULL) {
316 fprintf(stderr, "vnc: out of memory\n");
317 exit(1);
322 int buffer_empty(Buffer *buffer)
324 return buffer->offset == 0;
327 uint8_t *buffer_end(Buffer *buffer)
329 return buffer->buffer + buffer->offset;
332 void buffer_reset(Buffer *buffer)
334 buffer->offset = 0;
337 void buffer_append(Buffer *buffer, const void *data, size_t len)
339 memcpy(buffer->buffer + buffer->offset, data, len);
340 buffer->offset += len;
343 static void vnc_resize(VncState *vs)
345 DisplayState *ds = vs->ds;
346 int size_changed;
348 /* guest surface */
349 if (!vs->guest.ds)
350 vs->guest.ds = qemu_mallocz(sizeof(*vs->guest.ds));
351 if (ds_get_bytes_per_pixel(ds) != vs->guest.ds->pf.bytes_per_pixel)
352 console_color_init(ds);
353 vnc_colordepth(vs);
354 size_changed = ds_get_width(ds) != vs->guest.ds->width ||
355 ds_get_height(ds) != vs->guest.ds->height;
356 *(vs->guest.ds) = *(ds->surface);
357 if (size_changed) {
358 if (vs->csock != -1 && vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
359 vnc_write_u8(vs, 0); /* msg id */
360 vnc_write_u8(vs, 0);
361 vnc_write_u16(vs, 1); /* number of rects */
362 vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
363 VNC_ENCODING_DESKTOPRESIZE);
364 vnc_flush(vs);
367 memset(vs->guest.dirty, 0xFF, sizeof(vs->guest.dirty));
369 /* server surface */
370 if (!vs->server.ds)
371 vs->server.ds = qemu_mallocz(sizeof(*vs->server.ds));
372 if (vs->server.ds->data)
373 qemu_free(vs->server.ds->data);
374 *(vs->server.ds) = *(ds->surface);
375 vs->server.ds->data = qemu_mallocz(vs->server.ds->linesize *
376 vs->server.ds->height);
377 memset(vs->server.dirty, 0xFF, sizeof(vs->guest.dirty));
380 static void vnc_dpy_resize(DisplayState *ds)
382 VncDisplay *vd = ds->opaque;
383 VncState *vs = vd->clients;
384 while (vs != NULL) {
385 vnc_resize(vs);
386 vs = vs->next;
390 /* fastest code */
391 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
393 vnc_write(vs, pixels, size);
396 /* slowest but generic code. */
397 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
399 uint8_t r, g, b;
401 r = ((((v & vs->server.ds->pf.rmask) >> vs->server.ds->pf.rshift) << vs->clientds.pf.rbits) >>
402 vs->server.ds->pf.rbits);
403 g = ((((v & vs->server.ds->pf.gmask) >> vs->server.ds->pf.gshift) << vs->clientds.pf.gbits) >>
404 vs->server.ds->pf.gbits);
405 b = ((((v & vs->server.ds->pf.bmask) >> vs->server.ds->pf.bshift) << vs->clientds.pf.bbits) >>
406 vs->server.ds->pf.bbits);
407 v = (r << vs->clientds.pf.rshift) |
408 (g << vs->clientds.pf.gshift) |
409 (b << vs->clientds.pf.bshift);
410 switch(vs->clientds.pf.bytes_per_pixel) {
411 case 1:
412 buf[0] = v;
413 break;
414 case 2:
415 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
416 buf[0] = v >> 8;
417 buf[1] = v;
418 } else {
419 buf[1] = v >> 8;
420 buf[0] = v;
422 break;
423 default:
424 case 4:
425 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
426 buf[0] = v >> 24;
427 buf[1] = v >> 16;
428 buf[2] = v >> 8;
429 buf[3] = v;
430 } else {
431 buf[3] = v >> 24;
432 buf[2] = v >> 16;
433 buf[1] = v >> 8;
434 buf[0] = v;
436 break;
440 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
442 uint8_t buf[4];
444 if (vs->server.ds->pf.bytes_per_pixel == 4) {
445 uint32_t *pixels = pixels1;
446 int n, i;
447 n = size >> 2;
448 for(i = 0; i < n; i++) {
449 vnc_convert_pixel(vs, buf, pixels[i]);
450 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
452 } else if (vs->server.ds->pf.bytes_per_pixel == 2) {
453 uint16_t *pixels = pixels1;
454 int n, i;
455 n = size >> 1;
456 for(i = 0; i < n; i++) {
457 vnc_convert_pixel(vs, buf, pixels[i]);
458 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
460 } else if (vs->server.ds->pf.bytes_per_pixel == 1) {
461 uint8_t *pixels = pixels1;
462 int n, i;
463 n = size;
464 for(i = 0; i < n; i++) {
465 vnc_convert_pixel(vs, buf, pixels[i]);
466 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
468 } else {
469 fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
473 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
475 int i;
476 uint8_t *row;
478 row = vs->server.ds->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
479 for (i = 0; i < h; i++) {
480 vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
481 row += ds_get_linesize(vs->ds);
485 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
487 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
488 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
491 #define BPP 8
492 #include "vnchextile.h"
493 #undef BPP
495 #define BPP 16
496 #include "vnchextile.h"
497 #undef BPP
499 #define BPP 32
500 #include "vnchextile.h"
501 #undef BPP
503 #define GENERIC
504 #define BPP 8
505 #include "vnchextile.h"
506 #undef BPP
507 #undef GENERIC
509 #define GENERIC
510 #define BPP 16
511 #include "vnchextile.h"
512 #undef BPP
513 #undef GENERIC
515 #define GENERIC
516 #define BPP 32
517 #include "vnchextile.h"
518 #undef BPP
519 #undef GENERIC
521 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
523 int i, j;
524 int has_fg, has_bg;
525 uint8_t *last_fg, *last_bg;
527 last_fg = (uint8_t *) qemu_malloc(vs->server.ds->pf.bytes_per_pixel);
528 last_bg = (uint8_t *) qemu_malloc(vs->server.ds->pf.bytes_per_pixel);
529 has_fg = has_bg = 0;
530 for (j = y; j < (y + h); j += 16) {
531 for (i = x; i < (x + w); i += 16) {
532 vs->send_hextile_tile(vs, i, j,
533 MIN(16, x + w - i), MIN(16, y + h - j),
534 last_bg, last_fg, &has_bg, &has_fg);
537 free(last_fg);
538 free(last_bg);
542 static void vnc_zlib_init(VncState *vs)
544 int i;
545 for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++)
546 vs->zlib_stream[i].opaque = NULL;
549 static void vnc_zlib_start(VncState *vs)
551 buffer_reset(&vs->zlib);
553 // make the output buffer be the zlib buffer, so we can compress it later
554 vs->zlib_tmp = vs->output;
555 vs->output = vs->zlib;
558 static int vnc_zlib_stop(VncState *vs, int stream_id)
560 z_streamp zstream = &vs->zlib_stream[stream_id];
561 int previous_out;
563 // switch back to normal output/zlib buffers
564 vs->zlib = vs->output;
565 vs->output = vs->zlib_tmp;
567 // compress the zlib buffer
569 // initialize the stream
570 // XXX need one stream per session
571 if (zstream->opaque != vs) {
572 int err;
574 VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id);
575 VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
576 zstream->zalloc = Z_NULL;
577 zstream->zfree = Z_NULL;
579 err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
580 MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
582 if (err != Z_OK) {
583 fprintf(stderr, "VNC: error initializing zlib\n");
584 return -1;
587 zstream->opaque = vs;
590 // XXX what to do if tight_compression changed in between?
592 // reserve memory in output buffer
593 buffer_reserve(&vs->output, vs->zlib.offset + 64);
595 // set pointers
596 zstream->next_in = vs->zlib.buffer;
597 zstream->avail_in = vs->zlib.offset;
598 zstream->next_out = vs->output.buffer + vs->output.offset;
599 zstream->avail_out = vs->output.capacity - vs->output.offset;
600 zstream->data_type = Z_BINARY;
601 previous_out = zstream->total_out;
603 // start encoding
604 if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
605 fprintf(stderr, "VNC: error during zlib compression\n");
606 return -1;
609 vs->output.offset = vs->output.capacity - zstream->avail_out;
610 return zstream->total_out - previous_out;
613 static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)
615 int old_offset, new_offset, bytes_written;
617 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
619 // remember where we put in the follow-up size
620 old_offset = vs->output.offset;
621 vnc_write_s32(vs, 0);
623 // compress the stream
624 vnc_zlib_start(vs);
625 send_framebuffer_update_raw(vs, x, y, w, h);
626 bytes_written = vnc_zlib_stop(vs, 0);
628 if (bytes_written == -1)
629 return;
631 // hack in the size
632 new_offset = vs->output.offset;
633 vs->output.offset = old_offset;
634 vnc_write_u32(vs, bytes_written);
635 vs->output.offset = new_offset;
638 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
640 switch(vs->vnc_encoding) {
641 case VNC_ENCODING_ZLIB:
642 send_framebuffer_update_zlib(vs, x, y, w, h);
643 break;
644 case VNC_ENCODING_HEXTILE:
645 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
646 send_framebuffer_update_hextile(vs, x, y, w, h);
647 break;
648 default:
649 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
650 send_framebuffer_update_raw(vs, x, y, w, h);
651 break;
655 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
657 uint8_t *src_row;
658 uint8_t *dst_row;
659 int y,pitch,depth;
661 /* send bitblit op to the vnc client */
662 vnc_write_u8(vs, 0); /* msg id */
663 vnc_write_u8(vs, 0);
664 vnc_write_u16(vs, 1); /* number of rects */
665 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
666 vnc_write_u16(vs, src_x);
667 vnc_write_u16(vs, src_y);
668 vnc_flush(vs);
670 /* do bitblit op on the local surface too */
671 pitch = ds_get_linesize(vs->ds);
672 depth = ds_get_bytes_per_pixel(vs->ds);
673 src_row = vs->server.ds->data + pitch * src_y + depth * src_x;
674 dst_row = vs->server.ds->data + pitch * dst_y + depth * dst_x;
675 if (dst_y > src_y) {
676 /* copy backwards */
677 src_row += pitch * (h-1);
678 dst_row += pitch * (h-1);
679 pitch = -pitch;
681 for (y = 0; y < h; y++) {
682 memmove(dst_row, src_row, w * depth);
683 src_row += pitch;
684 dst_row += pitch;
688 static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
690 VncDisplay *vd = ds->opaque;
691 VncState *vs, *vn;
693 for (vs = vd->clients; vs != NULL; vs = vn) {
694 vn = vs->next;
695 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
696 vs->force_update = 1;
697 vnc_update_client(vs);
698 /* vs might be free()ed here */
702 for (vs = vd->clients; vs != NULL; vs = vs->next) {
703 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
704 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
705 else /* TODO */
706 vnc_update(vs, dst_x, dst_y, w, h);
710 static int find_and_clear_dirty_height(struct VncSurface *s,
711 int y, int last_x, int x)
713 int h;
715 for (h = 1; h < (s->ds->height - y); h++) {
716 int tmp_x;
717 if (!vnc_get_bit(s->dirty[y + h], last_x))
718 break;
719 for (tmp_x = last_x; tmp_x < x; tmp_x++)
720 vnc_clear_bit(s->dirty[y + h], tmp_x);
723 return h;
726 static void vnc_update_client(void *opaque)
728 VncState *vs = opaque;
729 if (vs->need_update && vs->csock != -1) {
730 int y;
731 uint8_t *guest_row;
732 uint8_t *server_row;
733 int cmp_bytes;
734 uint32_t width_mask[VNC_DIRTY_WORDS];
735 int n_rectangles;
736 int saved_offset;
737 int has_dirty = 0;
739 if (vs->output.offset && !vs->audio_cap && !vs->force_update) {
740 /* kernel send buffers are full -> drop frames to throttle */
741 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
742 return;
745 vga_hw_update();
748 * Walk through the guest dirty map.
749 * Check and copy modified bits from guest to server surface.
750 * Update server dirty map.
752 vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
753 cmp_bytes = 16 * ds_get_bytes_per_pixel(vs->ds);
754 guest_row = vs->guest.ds->data;
755 server_row = vs->server.ds->data;
756 for (y = 0; y < vs->guest.ds->height; y++) {
757 if (vnc_and_bits(vs->guest.dirty[y], width_mask, VNC_DIRTY_WORDS)) {
758 int x;
759 uint8_t *guest_ptr;
760 uint8_t *server_ptr;
762 guest_ptr = guest_row;
763 server_ptr = server_row;
765 for (x = 0; x < vs->guest.ds->width;
766 x += 16, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
767 if (!vnc_get_bit(vs->guest.dirty[y], (x / 16)))
768 continue;
769 vnc_clear_bit(vs->guest.dirty[y], (x / 16));
770 if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0)
771 continue;
772 memcpy(server_ptr, guest_ptr, cmp_bytes);
773 vnc_set_bit(vs->server.dirty[y], (x / 16));
774 has_dirty++;
777 guest_row += ds_get_linesize(vs->ds);
778 server_row += ds_get_linesize(vs->ds);
781 if (!has_dirty && !vs->audio_cap && !vs->force_update) {
782 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
783 return;
787 * Send screen updates to the vnc client using the server
788 * surface and server dirty map. guest surface updates
789 * happening in parallel don't disturb us, the next pass will
790 * send them to the client.
792 n_rectangles = 0;
793 vnc_write_u8(vs, 0); /* msg id */
794 vnc_write_u8(vs, 0);
795 saved_offset = vs->output.offset;
796 vnc_write_u16(vs, 0);
798 for (y = 0; y < vs->server.ds->height; y++) {
799 int x;
800 int last_x = -1;
801 for (x = 0; x < vs->server.ds->width / 16; x++) {
802 if (vnc_get_bit(vs->server.dirty[y], x)) {
803 if (last_x == -1) {
804 last_x = x;
806 vnc_clear_bit(vs->server.dirty[y], x);
807 } else {
808 if (last_x != -1) {
809 int h = find_and_clear_dirty_height(&vs->server, y, last_x, x);
810 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
811 n_rectangles++;
813 last_x = -1;
816 if (last_x != -1) {
817 int h = find_and_clear_dirty_height(&vs->server, y, last_x, x);
818 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
819 n_rectangles++;
822 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
823 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
824 vnc_flush(vs);
825 vs->force_update = 0;
829 if (vs->csock != -1) {
830 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
831 } else {
832 vnc_disconnect_finish(vs);
837 /* audio */
838 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
840 VncState *vs = opaque;
842 switch (cmd) {
843 case AUD_CNOTIFY_DISABLE:
844 vnc_write_u8(vs, 255);
845 vnc_write_u8(vs, 1);
846 vnc_write_u16(vs, 0);
847 vnc_flush(vs);
848 break;
850 case AUD_CNOTIFY_ENABLE:
851 vnc_write_u8(vs, 255);
852 vnc_write_u8(vs, 1);
853 vnc_write_u16(vs, 1);
854 vnc_flush(vs);
855 break;
859 static void audio_capture_destroy(void *opaque)
863 static void audio_capture(void *opaque, void *buf, int size)
865 VncState *vs = opaque;
867 vnc_write_u8(vs, 255);
868 vnc_write_u8(vs, 1);
869 vnc_write_u16(vs, 2);
870 vnc_write_u32(vs, size);
871 vnc_write(vs, buf, size);
872 vnc_flush(vs);
875 static void audio_add(VncState *vs)
877 Monitor *mon = cur_mon;
878 struct audio_capture_ops ops;
880 if (vs->audio_cap) {
881 monitor_printf(mon, "audio already running\n");
882 return;
885 ops.notify = audio_capture_notify;
886 ops.destroy = audio_capture_destroy;
887 ops.capture = audio_capture;
889 vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
890 if (!vs->audio_cap) {
891 monitor_printf(mon, "Failed to add audio capture\n");
895 static void audio_del(VncState *vs)
897 if (vs->audio_cap) {
898 AUD_del_capture(vs->audio_cap, vs);
899 vs->audio_cap = NULL;
903 static void vnc_disconnect_start(VncState *vs)
905 if (vs->csock == -1)
906 return;
907 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
908 closesocket(vs->csock);
909 vs->csock = -1;
912 static void vnc_disconnect_finish(VncState *vs)
914 qemu_del_timer(vs->timer);
915 qemu_free_timer(vs->timer);
916 if (vs->input.buffer) qemu_free(vs->input.buffer);
917 if (vs->output.buffer) qemu_free(vs->output.buffer);
918 #ifdef CONFIG_VNC_TLS
919 vnc_tls_client_cleanup(vs);
920 #endif /* CONFIG_VNC_TLS */
921 #ifdef CONFIG_VNC_SASL
922 vnc_sasl_client_cleanup(vs);
923 #endif /* CONFIG_VNC_SASL */
924 audio_del(vs);
926 VncState *p, *parent = NULL;
927 for (p = vs->vd->clients; p != NULL; p = p->next) {
928 if (p == vs) {
929 if (parent)
930 parent->next = p->next;
931 else
932 vs->vd->clients = p->next;
933 break;
935 parent = p;
937 if (!vs->vd->clients)
938 dcl->idle = 1;
940 qemu_free(vs->server.ds->data);
941 qemu_free(vs->server.ds);
942 qemu_free(vs->guest.ds);
943 qemu_free(vs);
946 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
948 if (ret == 0 || ret == -1) {
949 if (ret == -1) {
950 switch (last_errno) {
951 case EINTR:
952 case EAGAIN:
953 #ifdef _WIN32
954 case WSAEWOULDBLOCK:
955 #endif
956 return 0;
957 default:
958 break;
962 VNC_DEBUG("Closing down client sock: ret %d, errno %d\n",
963 ret, ret < 0 ? last_errno : 0);
964 vnc_disconnect_start(vs);
966 return 0;
968 return ret;
972 void vnc_client_error(VncState *vs)
974 VNC_DEBUG("Closing down client sock: protocol error\n");
975 vnc_disconnect_start(vs);
980 * Called to write a chunk of data to the client socket. The data may
981 * be the raw data, or may have already been encoded by SASL.
982 * The data will be written either straight onto the socket, or
983 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
985 * NB, it is theoretically possible to have 2 layers of encryption,
986 * both SASL, and this TLS layer. It is highly unlikely in practice
987 * though, since SASL encryption will typically be a no-op if TLS
988 * is active
990 * Returns the number of bytes written, which may be less than
991 * the requested 'datalen' if the socket would block. Returns
992 * -1 on error, and disconnects the client socket.
994 long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
996 long ret;
997 #ifdef CONFIG_VNC_TLS
998 if (vs->tls.session) {
999 ret = gnutls_write(vs->tls.session, data, datalen);
1000 if (ret < 0) {
1001 if (ret == GNUTLS_E_AGAIN)
1002 errno = EAGAIN;
1003 else
1004 errno = EIO;
1005 ret = -1;
1007 } else
1008 #endif /* CONFIG_VNC_TLS */
1009 ret = send(vs->csock, (const void *)data, datalen, 0);
1010 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1011 return vnc_client_io_error(vs, ret, socket_error());
1016 * Called to write buffered data to the client socket, when not
1017 * using any SASL SSF encryption layers. Will write as much data
1018 * as possible without blocking. If all buffered data is written,
1019 * will switch the FD poll() handler back to read monitoring.
1021 * Returns the number of bytes written, which may be less than
1022 * the buffered output data if the socket would block. Returns
1023 * -1 on error, and disconnects the client socket.
1025 static long vnc_client_write_plain(VncState *vs)
1027 long ret;
1029 #ifdef CONFIG_VNC_SASL
1030 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1031 vs->output.buffer, vs->output.capacity, vs->output.offset,
1032 vs->sasl.waitWriteSSF);
1034 if (vs->sasl.conn &&
1035 vs->sasl.runSSF &&
1036 vs->sasl.waitWriteSSF) {
1037 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1038 if (ret)
1039 vs->sasl.waitWriteSSF -= ret;
1040 } else
1041 #endif /* CONFIG_VNC_SASL */
1042 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1043 if (!ret)
1044 return 0;
1046 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
1047 vs->output.offset -= ret;
1049 if (vs->output.offset == 0) {
1050 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1053 return ret;
1058 * First function called whenever there is data to be written to
1059 * the client socket. Will delegate actual work according to whether
1060 * SASL SSF layers are enabled (thus requiring encryption calls)
1062 void vnc_client_write(void *opaque)
1064 long ret;
1065 VncState *vs = opaque;
1067 #ifdef CONFIG_VNC_SASL
1068 if (vs->sasl.conn &&
1069 vs->sasl.runSSF &&
1070 !vs->sasl.waitWriteSSF)
1071 ret = vnc_client_write_sasl(vs);
1072 else
1073 #endif /* CONFIG_VNC_SASL */
1074 ret = vnc_client_write_plain(vs);
1077 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1079 vs->read_handler = func;
1080 vs->read_handler_expect = expecting;
1085 * Called to read a chunk of data from the client socket. The data may
1086 * be the raw data, or may need to be further decoded by SASL.
1087 * The data will be read either straight from to the socket, or
1088 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1090 * NB, it is theoretically possible to have 2 layers of encryption,
1091 * both SASL, and this TLS layer. It is highly unlikely in practice
1092 * though, since SASL encryption will typically be a no-op if TLS
1093 * is active
1095 * Returns the number of bytes read, which may be less than
1096 * the requested 'datalen' if the socket would block. Returns
1097 * -1 on error, and disconnects the client socket.
1099 long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1101 long ret;
1102 #ifdef CONFIG_VNC_TLS
1103 if (vs->tls.session) {
1104 ret = gnutls_read(vs->tls.session, data, datalen);
1105 if (ret < 0) {
1106 if (ret == GNUTLS_E_AGAIN)
1107 errno = EAGAIN;
1108 else
1109 errno = EIO;
1110 ret = -1;
1112 } else
1113 #endif /* CONFIG_VNC_TLS */
1114 ret = recv(vs->csock, (void *)data, datalen, 0);
1115 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1116 return vnc_client_io_error(vs, ret, socket_error());
1121 * Called to read data from the client socket to the input buffer,
1122 * when not using any SASL SSF encryption layers. Will read as much
1123 * data as possible without blocking.
1125 * Returns the number of bytes read. Returns -1 on error, and
1126 * disconnects the client socket.
1128 static long vnc_client_read_plain(VncState *vs)
1130 int ret;
1131 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1132 vs->input.buffer, vs->input.capacity, vs->input.offset);
1133 buffer_reserve(&vs->input, 4096);
1134 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1135 if (!ret)
1136 return 0;
1137 vs->input.offset += ret;
1138 return ret;
1143 * First function called whenever there is more data to be read from
1144 * the client socket. Will delegate actual work according to whether
1145 * SASL SSF layers are enabled (thus requiring decryption calls)
1147 void vnc_client_read(void *opaque)
1149 VncState *vs = opaque;
1150 long ret;
1152 #ifdef CONFIG_VNC_SASL
1153 if (vs->sasl.conn && vs->sasl.runSSF)
1154 ret = vnc_client_read_sasl(vs);
1155 else
1156 #endif /* CONFIG_VNC_SASL */
1157 ret = vnc_client_read_plain(vs);
1158 if (!ret) {
1159 if (vs->csock == -1)
1160 vnc_disconnect_finish(vs);
1161 return;
1164 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1165 size_t len = vs->read_handler_expect;
1166 int ret;
1168 ret = vs->read_handler(vs, vs->input.buffer, len);
1169 if (vs->csock == -1) {
1170 vnc_disconnect_finish(vs);
1171 return;
1174 if (!ret) {
1175 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
1176 vs->input.offset -= len;
1177 } else {
1178 vs->read_handler_expect = ret;
1183 void vnc_write(VncState *vs, const void *data, size_t len)
1185 buffer_reserve(&vs->output, len);
1187 if (vs->csock != -1 && buffer_empty(&vs->output)) {
1188 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1191 buffer_append(&vs->output, data, len);
1194 void vnc_write_s32(VncState *vs, int32_t value)
1196 vnc_write_u32(vs, *(uint32_t *)&value);
1199 void vnc_write_u32(VncState *vs, uint32_t value)
1201 uint8_t buf[4];
1203 buf[0] = (value >> 24) & 0xFF;
1204 buf[1] = (value >> 16) & 0xFF;
1205 buf[2] = (value >> 8) & 0xFF;
1206 buf[3] = value & 0xFF;
1208 vnc_write(vs, buf, 4);
1211 void vnc_write_u16(VncState *vs, uint16_t value)
1213 uint8_t buf[2];
1215 buf[0] = (value >> 8) & 0xFF;
1216 buf[1] = value & 0xFF;
1218 vnc_write(vs, buf, 2);
1221 void vnc_write_u8(VncState *vs, uint8_t value)
1223 vnc_write(vs, (char *)&value, 1);
1226 void vnc_flush(VncState *vs)
1228 if (vs->csock != -1 && vs->output.offset)
1229 vnc_client_write(vs);
1232 uint8_t read_u8(uint8_t *data, size_t offset)
1234 return data[offset];
1237 uint16_t read_u16(uint8_t *data, size_t offset)
1239 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1242 int32_t read_s32(uint8_t *data, size_t offset)
1244 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1245 (data[offset + 2] << 8) | data[offset + 3]);
1248 uint32_t read_u32(uint8_t *data, size_t offset)
1250 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1251 (data[offset + 2] << 8) | data[offset + 3]);
1254 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1258 static void check_pointer_type_change(VncState *vs, int absolute)
1260 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1261 vnc_write_u8(vs, 0);
1262 vnc_write_u8(vs, 0);
1263 vnc_write_u16(vs, 1);
1264 vnc_framebuffer_update(vs, absolute, 0,
1265 ds_get_width(vs->ds), ds_get_height(vs->ds),
1266 VNC_ENCODING_POINTER_TYPE_CHANGE);
1267 vnc_flush(vs);
1269 vs->absolute = absolute;
1272 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1274 int buttons = 0;
1275 int dz = 0;
1277 if (button_mask & 0x01)
1278 buttons |= MOUSE_EVENT_LBUTTON;
1279 if (button_mask & 0x02)
1280 buttons |= MOUSE_EVENT_MBUTTON;
1281 if (button_mask & 0x04)
1282 buttons |= MOUSE_EVENT_RBUTTON;
1283 if (button_mask & 0x08)
1284 dz = -1;
1285 if (button_mask & 0x10)
1286 dz = 1;
1288 if (vs->absolute) {
1289 kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
1290 y * 0x7FFF / (ds_get_height(vs->ds) - 1),
1291 dz, buttons);
1292 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1293 x -= 0x7FFF;
1294 y -= 0x7FFF;
1296 kbd_mouse_event(x, y, dz, buttons);
1297 } else {
1298 if (vs->last_x != -1)
1299 kbd_mouse_event(x - vs->last_x,
1300 y - vs->last_y,
1301 dz, buttons);
1302 vs->last_x = x;
1303 vs->last_y = y;
1306 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1309 static void reset_keys(VncState *vs)
1311 int i;
1312 for(i = 0; i < 256; i++) {
1313 if (vs->modifiers_state[i]) {
1314 if (i & 0x80)
1315 kbd_put_keycode(0xe0);
1316 kbd_put_keycode(i | 0x80);
1317 vs->modifiers_state[i] = 0;
1322 static void press_key(VncState *vs, int keysym)
1324 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
1325 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
1328 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1330 /* QEMU console switch */
1331 switch(keycode) {
1332 case 0x2a: /* Left Shift */
1333 case 0x36: /* Right Shift */
1334 case 0x1d: /* Left CTRL */
1335 case 0x9d: /* Right CTRL */
1336 case 0x38: /* Left ALT */
1337 case 0xb8: /* Right ALT */
1338 if (down)
1339 vs->modifiers_state[keycode] = 1;
1340 else
1341 vs->modifiers_state[keycode] = 0;
1342 break;
1343 case 0x02 ... 0x0a: /* '1' to '9' keys */
1344 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1345 /* Reset the modifiers sent to the current console */
1346 reset_keys(vs);
1347 console_select(keycode - 0x02);
1348 return;
1350 break;
1351 case 0x3a: /* CapsLock */
1352 case 0x45: /* NumLock */
1353 if (!down)
1354 vs->modifiers_state[keycode] ^= 1;
1355 break;
1358 if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1359 /* If the numlock state needs to change then simulate an additional
1360 keypress before sending this one. This will happen if the user
1361 toggles numlock away from the VNC window.
1363 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1364 if (!vs->modifiers_state[0x45]) {
1365 vs->modifiers_state[0x45] = 1;
1366 press_key(vs, 0xff7f);
1368 } else {
1369 if (vs->modifiers_state[0x45]) {
1370 vs->modifiers_state[0x45] = 0;
1371 press_key(vs, 0xff7f);
1376 if (is_graphic_console()) {
1377 if (keycode & 0x80)
1378 kbd_put_keycode(0xe0);
1379 if (down)
1380 kbd_put_keycode(keycode & 0x7f);
1381 else
1382 kbd_put_keycode(keycode | 0x80);
1383 } else {
1384 /* QEMU console emulation */
1385 if (down) {
1386 int numlock = vs->modifiers_state[0x45];
1387 switch (keycode) {
1388 case 0x2a: /* Left Shift */
1389 case 0x36: /* Right Shift */
1390 case 0x1d: /* Left CTRL */
1391 case 0x9d: /* Right CTRL */
1392 case 0x38: /* Left ALT */
1393 case 0xb8: /* Right ALT */
1394 break;
1395 case 0xc8:
1396 kbd_put_keysym(QEMU_KEY_UP);
1397 break;
1398 case 0xd0:
1399 kbd_put_keysym(QEMU_KEY_DOWN);
1400 break;
1401 case 0xcb:
1402 kbd_put_keysym(QEMU_KEY_LEFT);
1403 break;
1404 case 0xcd:
1405 kbd_put_keysym(QEMU_KEY_RIGHT);
1406 break;
1407 case 0xd3:
1408 kbd_put_keysym(QEMU_KEY_DELETE);
1409 break;
1410 case 0xc7:
1411 kbd_put_keysym(QEMU_KEY_HOME);
1412 break;
1413 case 0xcf:
1414 kbd_put_keysym(QEMU_KEY_END);
1415 break;
1416 case 0xc9:
1417 kbd_put_keysym(QEMU_KEY_PAGEUP);
1418 break;
1419 case 0xd1:
1420 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1421 break;
1423 case 0x47:
1424 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1425 break;
1426 case 0x48:
1427 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1428 break;
1429 case 0x49:
1430 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1431 break;
1432 case 0x4b:
1433 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
1434 break;
1435 case 0x4c:
1436 kbd_put_keysym('5');
1437 break;
1438 case 0x4d:
1439 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
1440 break;
1441 case 0x4f:
1442 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
1443 break;
1444 case 0x50:
1445 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
1446 break;
1447 case 0x51:
1448 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
1449 break;
1450 case 0x52:
1451 kbd_put_keysym('0');
1452 break;
1453 case 0x53:
1454 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
1455 break;
1457 case 0xb5:
1458 kbd_put_keysym('/');
1459 break;
1460 case 0x37:
1461 kbd_put_keysym('*');
1462 break;
1463 case 0x4a:
1464 kbd_put_keysym('-');
1465 break;
1466 case 0x4e:
1467 kbd_put_keysym('+');
1468 break;
1469 case 0x9c:
1470 kbd_put_keysym('\n');
1471 break;
1473 default:
1474 kbd_put_keysym(sym);
1475 break;
1481 static void key_event(VncState *vs, int down, uint32_t sym)
1483 int keycode;
1485 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1486 sym = sym - 'A' + 'a';
1488 keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
1489 do_key_event(vs, down, keycode, sym);
1492 static void ext_key_event(VncState *vs, int down,
1493 uint32_t sym, uint16_t keycode)
1495 /* if the user specifies a keyboard layout, always use it */
1496 if (keyboard_layout)
1497 key_event(vs, down, sym);
1498 else
1499 do_key_event(vs, down, keycode, sym);
1502 static void framebuffer_update_request(VncState *vs, int incremental,
1503 int x_position, int y_position,
1504 int w, int h)
1506 if (x_position > ds_get_width(vs->ds))
1507 x_position = ds_get_width(vs->ds);
1508 if (y_position > ds_get_height(vs->ds))
1509 y_position = ds_get_height(vs->ds);
1510 if (x_position + w >= ds_get_width(vs->ds))
1511 w = ds_get_width(vs->ds) - x_position;
1512 if (y_position + h >= ds_get_height(vs->ds))
1513 h = ds_get_height(vs->ds) - y_position;
1515 int i;
1516 vs->need_update = 1;
1517 if (!incremental) {
1518 vs->force_update = 1;
1519 for (i = 0; i < h; i++) {
1520 vnc_set_bits(vs->guest.dirty[y_position + i],
1521 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1522 vnc_set_bits(vs->server.dirty[y_position + i],
1523 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1528 static void send_ext_key_event_ack(VncState *vs)
1530 vnc_write_u8(vs, 0);
1531 vnc_write_u8(vs, 0);
1532 vnc_write_u16(vs, 1);
1533 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1534 VNC_ENCODING_EXT_KEY_EVENT);
1535 vnc_flush(vs);
1538 static void send_ext_audio_ack(VncState *vs)
1540 vnc_write_u8(vs, 0);
1541 vnc_write_u8(vs, 0);
1542 vnc_write_u16(vs, 1);
1543 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1544 VNC_ENCODING_AUDIO);
1545 vnc_flush(vs);
1548 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1550 int i;
1551 unsigned int enc = 0;
1553 vnc_zlib_init(vs);
1554 vs->features = 0;
1555 vs->vnc_encoding = 0;
1556 vs->tight_compression = 9;
1557 vs->tight_quality = 9;
1558 vs->absolute = -1;
1560 for (i = n_encodings - 1; i >= 0; i--) {
1561 enc = encodings[i];
1562 switch (enc) {
1563 case VNC_ENCODING_RAW:
1564 vs->vnc_encoding = enc;
1565 break;
1566 case VNC_ENCODING_COPYRECT:
1567 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1568 break;
1569 case VNC_ENCODING_HEXTILE:
1570 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1571 vs->vnc_encoding = enc;
1572 break;
1573 case VNC_ENCODING_ZLIB:
1574 vs->features |= VNC_FEATURE_ZLIB_MASK;
1575 vs->vnc_encoding = enc;
1576 break;
1577 case VNC_ENCODING_DESKTOPRESIZE:
1578 vs->features |= VNC_FEATURE_RESIZE_MASK;
1579 break;
1580 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1581 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1582 break;
1583 case VNC_ENCODING_EXT_KEY_EVENT:
1584 send_ext_key_event_ack(vs);
1585 break;
1586 case VNC_ENCODING_AUDIO:
1587 send_ext_audio_ack(vs);
1588 break;
1589 case VNC_ENCODING_WMVi:
1590 vs->features |= VNC_FEATURE_WMVI_MASK;
1591 break;
1592 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1593 vs->tight_compression = (enc & 0x0F);
1594 break;
1595 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1596 vs->tight_quality = (enc & 0x0F);
1597 break;
1598 default:
1599 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1600 break;
1604 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1607 static void set_pixel_conversion(VncState *vs)
1609 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1610 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1611 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1612 vs->write_pixels = vnc_write_pixels_copy;
1613 switch (vs->ds->surface->pf.bits_per_pixel) {
1614 case 8:
1615 vs->send_hextile_tile = send_hextile_tile_8;
1616 break;
1617 case 16:
1618 vs->send_hextile_tile = send_hextile_tile_16;
1619 break;
1620 case 32:
1621 vs->send_hextile_tile = send_hextile_tile_32;
1622 break;
1624 } else {
1625 vs->write_pixels = vnc_write_pixels_generic;
1626 switch (vs->ds->surface->pf.bits_per_pixel) {
1627 case 8:
1628 vs->send_hextile_tile = send_hextile_tile_generic_8;
1629 break;
1630 case 16:
1631 vs->send_hextile_tile = send_hextile_tile_generic_16;
1632 break;
1633 case 32:
1634 vs->send_hextile_tile = send_hextile_tile_generic_32;
1635 break;
1640 static void set_pixel_format(VncState *vs,
1641 int bits_per_pixel, int depth,
1642 int big_endian_flag, int true_color_flag,
1643 int red_max, int green_max, int blue_max,
1644 int red_shift, int green_shift, int blue_shift)
1646 if (!true_color_flag) {
1647 vnc_client_error(vs);
1648 return;
1651 vs->clientds = *(vs->guest.ds);
1652 vs->clientds.pf.rmax = red_max;
1653 count_bits(vs->clientds.pf.rbits, red_max);
1654 vs->clientds.pf.rshift = red_shift;
1655 vs->clientds.pf.rmask = red_max << red_shift;
1656 vs->clientds.pf.gmax = green_max;
1657 count_bits(vs->clientds.pf.gbits, green_max);
1658 vs->clientds.pf.gshift = green_shift;
1659 vs->clientds.pf.gmask = green_max << green_shift;
1660 vs->clientds.pf.bmax = blue_max;
1661 count_bits(vs->clientds.pf.bbits, blue_max);
1662 vs->clientds.pf.bshift = blue_shift;
1663 vs->clientds.pf.bmask = blue_max << blue_shift;
1664 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1665 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1666 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1667 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1669 set_pixel_conversion(vs);
1671 vga_hw_invalidate();
1672 vga_hw_update();
1675 static void pixel_format_message (VncState *vs) {
1676 char pad[3] = { 0, 0, 0 };
1678 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1679 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
1681 #ifdef HOST_WORDS_BIGENDIAN
1682 vnc_write_u8(vs, 1); /* big-endian-flag */
1683 #else
1684 vnc_write_u8(vs, 0); /* big-endian-flag */
1685 #endif
1686 vnc_write_u8(vs, 1); /* true-color-flag */
1687 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1688 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1689 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1690 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1691 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1692 vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
1693 if (vs->ds->surface->pf.bits_per_pixel == 32)
1694 vs->send_hextile_tile = send_hextile_tile_32;
1695 else if (vs->ds->surface->pf.bits_per_pixel == 16)
1696 vs->send_hextile_tile = send_hextile_tile_16;
1697 else if (vs->ds->surface->pf.bits_per_pixel == 8)
1698 vs->send_hextile_tile = send_hextile_tile_8;
1699 vs->clientds = *(vs->ds->surface);
1700 vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG;
1701 vs->write_pixels = vnc_write_pixels_copy;
1703 vnc_write(vs, pad, 3); /* padding */
1706 static void vnc_dpy_setdata(DisplayState *ds)
1708 /* We don't have to do anything */
1711 static void vnc_colordepth(VncState *vs)
1713 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
1714 /* Sending a WMVi message to notify the client*/
1715 vnc_write_u8(vs, 0); /* msg id */
1716 vnc_write_u8(vs, 0);
1717 vnc_write_u16(vs, 1); /* number of rects */
1718 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
1719 ds_get_height(vs->ds), VNC_ENCODING_WMVi);
1720 pixel_format_message(vs);
1721 vnc_flush(vs);
1722 } else {
1723 set_pixel_conversion(vs);
1727 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1729 int i;
1730 uint16_t limit;
1732 switch (data[0]) {
1733 case 0:
1734 if (len == 1)
1735 return 20;
1737 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1738 read_u8(data, 6), read_u8(data, 7),
1739 read_u16(data, 8), read_u16(data, 10),
1740 read_u16(data, 12), read_u8(data, 14),
1741 read_u8(data, 15), read_u8(data, 16));
1742 break;
1743 case 2:
1744 if (len == 1)
1745 return 4;
1747 if (len == 4) {
1748 limit = read_u16(data, 2);
1749 if (limit > 0)
1750 return 4 + (limit * 4);
1751 } else
1752 limit = read_u16(data, 2);
1754 for (i = 0; i < limit; i++) {
1755 int32_t val = read_s32(data, 4 + (i * 4));
1756 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1759 set_encodings(vs, (int32_t *)(data + 4), limit);
1760 break;
1761 case 3:
1762 if (len == 1)
1763 return 10;
1765 framebuffer_update_request(vs,
1766 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1767 read_u16(data, 6), read_u16(data, 8));
1768 break;
1769 case 4:
1770 if (len == 1)
1771 return 8;
1773 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1774 break;
1775 case 5:
1776 if (len == 1)
1777 return 6;
1779 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1780 break;
1781 case 6:
1782 if (len == 1)
1783 return 8;
1785 if (len == 8) {
1786 uint32_t dlen = read_u32(data, 4);
1787 if (dlen > 0)
1788 return 8 + dlen;
1791 client_cut_text(vs, read_u32(data, 4), data + 8);
1792 break;
1793 case 255:
1794 if (len == 1)
1795 return 2;
1797 switch (read_u8(data, 1)) {
1798 case 0:
1799 if (len == 2)
1800 return 12;
1802 ext_key_event(vs, read_u16(data, 2),
1803 read_u32(data, 4), read_u32(data, 8));
1804 break;
1805 case 1:
1806 if (len == 2)
1807 return 4;
1809 switch (read_u16 (data, 2)) {
1810 case 0:
1811 audio_add(vs);
1812 break;
1813 case 1:
1814 audio_del(vs);
1815 break;
1816 case 2:
1817 if (len == 4)
1818 return 10;
1819 switch (read_u8(data, 4)) {
1820 case 0: vs->as.fmt = AUD_FMT_U8; break;
1821 case 1: vs->as.fmt = AUD_FMT_S8; break;
1822 case 2: vs->as.fmt = AUD_FMT_U16; break;
1823 case 3: vs->as.fmt = AUD_FMT_S16; break;
1824 case 4: vs->as.fmt = AUD_FMT_U32; break;
1825 case 5: vs->as.fmt = AUD_FMT_S32; break;
1826 default:
1827 printf("Invalid audio format %d\n", read_u8(data, 4));
1828 vnc_client_error(vs);
1829 break;
1831 vs->as.nchannels = read_u8(data, 5);
1832 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
1833 printf("Invalid audio channel coount %d\n",
1834 read_u8(data, 5));
1835 vnc_client_error(vs);
1836 break;
1838 vs->as.freq = read_u32(data, 6);
1839 break;
1840 default:
1841 printf ("Invalid audio message %d\n", read_u8(data, 4));
1842 vnc_client_error(vs);
1843 break;
1845 break;
1847 default:
1848 printf("Msg: %d\n", read_u16(data, 0));
1849 vnc_client_error(vs);
1850 break;
1852 break;
1853 default:
1854 printf("Msg: %d\n", data[0]);
1855 vnc_client_error(vs);
1856 break;
1859 vnc_read_when(vs, protocol_client_msg, 1);
1860 return 0;
1863 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1865 char buf[1024];
1866 int size;
1868 vnc_write_u16(vs, ds_get_width(vs->ds));
1869 vnc_write_u16(vs, ds_get_height(vs->ds));
1871 pixel_format_message(vs);
1873 if (qemu_name)
1874 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1875 else
1876 size = snprintf(buf, sizeof(buf), "QEMU");
1878 vnc_write_u32(vs, size);
1879 vnc_write(vs, buf, size);
1880 vnc_flush(vs);
1882 vnc_read_when(vs, protocol_client_msg, 1);
1884 return 0;
1887 void start_client_init(VncState *vs)
1889 vnc_read_when(vs, protocol_client_init, 1);
1892 static void make_challenge(VncState *vs)
1894 int i;
1896 srand(time(NULL)+getpid()+getpid()*987654+rand());
1898 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1899 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1902 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1904 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1905 int i, j, pwlen;
1906 unsigned char key[8];
1908 if (!vs->vd->password || !vs->vd->password[0]) {
1909 VNC_DEBUG("No password configured on server");
1910 vnc_write_u32(vs, 1); /* Reject auth */
1911 if (vs->minor >= 8) {
1912 static const char err[] = "Authentication failed";
1913 vnc_write_u32(vs, sizeof(err));
1914 vnc_write(vs, err, sizeof(err));
1916 vnc_flush(vs);
1917 vnc_client_error(vs);
1918 return 0;
1921 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1923 /* Calculate the expected challenge response */
1924 pwlen = strlen(vs->vd->password);
1925 for (i=0; i<sizeof(key); i++)
1926 key[i] = i<pwlen ? vs->vd->password[i] : 0;
1927 deskey(key, EN0);
1928 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1929 des(response+j, response+j);
1931 /* Compare expected vs actual challenge response */
1932 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1933 VNC_DEBUG("Client challenge reponse did not match\n");
1934 vnc_write_u32(vs, 1); /* Reject auth */
1935 if (vs->minor >= 8) {
1936 static const char err[] = "Authentication failed";
1937 vnc_write_u32(vs, sizeof(err));
1938 vnc_write(vs, err, sizeof(err));
1940 vnc_flush(vs);
1941 vnc_client_error(vs);
1942 } else {
1943 VNC_DEBUG("Accepting VNC challenge response\n");
1944 vnc_write_u32(vs, 0); /* Accept auth */
1945 vnc_flush(vs);
1947 start_client_init(vs);
1949 return 0;
1952 void start_auth_vnc(VncState *vs)
1954 make_challenge(vs);
1955 /* Send client a 'random' challenge */
1956 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1957 vnc_flush(vs);
1959 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1963 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1965 /* We only advertise 1 auth scheme at a time, so client
1966 * must pick the one we sent. Verify this */
1967 if (data[0] != vs->vd->auth) { /* Reject auth */
1968 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
1969 vnc_write_u32(vs, 1);
1970 if (vs->minor >= 8) {
1971 static const char err[] = "Authentication failed";
1972 vnc_write_u32(vs, sizeof(err));
1973 vnc_write(vs, err, sizeof(err));
1975 vnc_client_error(vs);
1976 } else { /* Accept requested auth */
1977 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1978 switch (vs->vd->auth) {
1979 case VNC_AUTH_NONE:
1980 VNC_DEBUG("Accept auth none\n");
1981 if (vs->minor >= 8) {
1982 vnc_write_u32(vs, 0); /* Accept auth completion */
1983 vnc_flush(vs);
1985 start_client_init(vs);
1986 break;
1988 case VNC_AUTH_VNC:
1989 VNC_DEBUG("Start VNC auth\n");
1990 start_auth_vnc(vs);
1991 break;
1993 #ifdef CONFIG_VNC_TLS
1994 case VNC_AUTH_VENCRYPT:
1995 VNC_DEBUG("Accept VeNCrypt auth\n");;
1996 start_auth_vencrypt(vs);
1997 break;
1998 #endif /* CONFIG_VNC_TLS */
2000 #ifdef CONFIG_VNC_SASL
2001 case VNC_AUTH_SASL:
2002 VNC_DEBUG("Accept SASL auth\n");
2003 start_auth_sasl(vs);
2004 break;
2005 #endif /* CONFIG_VNC_SASL */
2007 default: /* Should not be possible, but just in case */
2008 VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth);
2009 vnc_write_u8(vs, 1);
2010 if (vs->minor >= 8) {
2011 static const char err[] = "Authentication failed";
2012 vnc_write_u32(vs, sizeof(err));
2013 vnc_write(vs, err, sizeof(err));
2015 vnc_client_error(vs);
2018 return 0;
2021 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2023 char local[13];
2025 memcpy(local, version, 12);
2026 local[12] = 0;
2028 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2029 VNC_DEBUG("Malformed protocol version %s\n", local);
2030 vnc_client_error(vs);
2031 return 0;
2033 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2034 if (vs->major != 3 ||
2035 (vs->minor != 3 &&
2036 vs->minor != 4 &&
2037 vs->minor != 5 &&
2038 vs->minor != 7 &&
2039 vs->minor != 8)) {
2040 VNC_DEBUG("Unsupported client version\n");
2041 vnc_write_u32(vs, VNC_AUTH_INVALID);
2042 vnc_flush(vs);
2043 vnc_client_error(vs);
2044 return 0;
2046 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
2047 * as equivalent to v3.3 by servers
2049 if (vs->minor == 4 || vs->minor == 5)
2050 vs->minor = 3;
2052 if (vs->minor == 3) {
2053 if (vs->vd->auth == VNC_AUTH_NONE) {
2054 VNC_DEBUG("Tell client auth none\n");
2055 vnc_write_u32(vs, vs->vd->auth);
2056 vnc_flush(vs);
2057 start_client_init(vs);
2058 } else if (vs->vd->auth == VNC_AUTH_VNC) {
2059 VNC_DEBUG("Tell client VNC auth\n");
2060 vnc_write_u32(vs, vs->vd->auth);
2061 vnc_flush(vs);
2062 start_auth_vnc(vs);
2063 } else {
2064 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
2065 vnc_write_u32(vs, VNC_AUTH_INVALID);
2066 vnc_flush(vs);
2067 vnc_client_error(vs);
2069 } else {
2070 VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
2071 vnc_write_u8(vs, 1); /* num auth */
2072 vnc_write_u8(vs, vs->vd->auth);
2073 vnc_read_when(vs, protocol_client_auth, 1);
2074 vnc_flush(vs);
2077 return 0;
2080 static void vnc_connect(VncDisplay *vd, int csock)
2082 VncState *vs = qemu_mallocz(sizeof(VncState));
2083 vs->csock = csock;
2085 VNC_DEBUG("New client on socket %d\n", csock);
2086 dcl->idle = 0;
2087 socket_set_nonblock(vs->csock);
2088 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
2090 vs->vd = vd;
2091 vs->ds = vd->ds;
2092 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
2093 vs->last_x = -1;
2094 vs->last_y = -1;
2096 vs->as.freq = 44100;
2097 vs->as.nchannels = 2;
2098 vs->as.fmt = AUD_FMT_S16;
2099 vs->as.endianness = 0;
2101 vnc_resize(vs);
2102 vnc_write(vs, "RFB 003.008\n", 12);
2103 vnc_flush(vs);
2104 vnc_read_when(vs, protocol_version, 12);
2105 reset_keys(vs);
2107 vs->next = vd->clients;
2108 vd->clients = vs;
2110 vnc_update_client(vs);
2111 /* vs might be free()ed here */
2114 static void vnc_listen_read(void *opaque)
2116 VncDisplay *vs = opaque;
2117 struct sockaddr_in addr;
2118 socklen_t addrlen = sizeof(addr);
2120 /* Catch-up */
2121 vga_hw_update();
2123 int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2124 if (csock != -1) {
2125 vnc_connect(vs, csock);
2129 void vnc_display_init(DisplayState *ds)
2131 VncDisplay *vs = qemu_mallocz(sizeof(*vs));
2133 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
2135 ds->opaque = vs;
2136 dcl->idle = 1;
2137 vnc_display = vs;
2139 vs->lsock = -1;
2141 vs->ds = ds;
2143 if (keyboard_layout)
2144 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
2145 else
2146 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
2148 if (!vs->kbd_layout)
2149 exit(1);
2151 dcl->dpy_copy = vnc_dpy_copy;
2152 dcl->dpy_update = vnc_dpy_update;
2153 dcl->dpy_resize = vnc_dpy_resize;
2154 dcl->dpy_setdata = vnc_dpy_setdata;
2155 register_displaychangelistener(ds, dcl);
2159 void vnc_display_close(DisplayState *ds)
2161 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2163 if (!vs)
2164 return;
2165 if (vs->display) {
2166 qemu_free(vs->display);
2167 vs->display = NULL;
2169 if (vs->lsock != -1) {
2170 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2171 close(vs->lsock);
2172 vs->lsock = -1;
2174 vs->auth = VNC_AUTH_INVALID;
2175 #ifdef CONFIG_VNC_TLS
2176 vs->subauth = VNC_AUTH_INVALID;
2177 vs->tls.x509verify = 0;
2178 #endif
2181 int vnc_display_password(DisplayState *ds, const char *password)
2183 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2185 if (vs->password) {
2186 qemu_free(vs->password);
2187 vs->password = NULL;
2189 if (password && password[0]) {
2190 if (!(vs->password = qemu_strdup(password)))
2191 return -1;
2194 return 0;
2197 char *vnc_display_local_addr(DisplayState *ds)
2199 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2201 return vnc_socket_local_addr("%s:%s", vs->lsock);
2204 int vnc_display_open(DisplayState *ds, const char *display)
2206 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2207 const char *options;
2208 int password = 0;
2209 int reverse = 0;
2210 int to_port = 0;
2211 #ifdef CONFIG_VNC_TLS
2212 int tls = 0, x509 = 0;
2213 #endif
2214 #ifdef CONFIG_VNC_SASL
2215 int sasl = 0;
2216 int saslErr;
2217 #endif
2218 int acl = 0;
2220 if (!vnc_display)
2221 return -1;
2222 vnc_display_close(ds);
2223 if (strcmp(display, "none") == 0)
2224 return 0;
2226 if (!(vs->display = strdup(display)))
2227 return -1;
2229 options = display;
2230 while ((options = strchr(options, ','))) {
2231 options++;
2232 if (strncmp(options, "password", 8) == 0) {
2233 password = 1; /* Require password auth */
2234 } else if (strncmp(options, "reverse", 7) == 0) {
2235 reverse = 1;
2236 } else if (strncmp(options, "to=", 3) == 0) {
2237 to_port = atoi(options+3) + 5900;
2238 #ifdef CONFIG_VNC_SASL
2239 } else if (strncmp(options, "sasl", 4) == 0) {
2240 sasl = 1; /* Require SASL auth */
2241 #endif
2242 #ifdef CONFIG_VNC_TLS
2243 } else if (strncmp(options, "tls", 3) == 0) {
2244 tls = 1; /* Require TLS */
2245 } else if (strncmp(options, "x509", 4) == 0) {
2246 char *start, *end;
2247 x509 = 1; /* Require x509 certificates */
2248 if (strncmp(options, "x509verify", 10) == 0)
2249 vs->tls.x509verify = 1; /* ...and verify client certs */
2251 /* Now check for 'x509=/some/path' postfix
2252 * and use that to setup x509 certificate/key paths */
2253 start = strchr(options, '=');
2254 end = strchr(options, ',');
2255 if (start && (!end || (start < end))) {
2256 int len = end ? end-(start+1) : strlen(start+1);
2257 char *path = qemu_strndup(start + 1, len);
2259 VNC_DEBUG("Trying certificate path '%s'\n", path);
2260 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2261 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2262 qemu_free(path);
2263 qemu_free(vs->display);
2264 vs->display = NULL;
2265 return -1;
2267 qemu_free(path);
2268 } else {
2269 fprintf(stderr, "No certificate path provided\n");
2270 qemu_free(vs->display);
2271 vs->display = NULL;
2272 return -1;
2274 #endif
2275 } else if (strncmp(options, "acl", 3) == 0) {
2276 acl = 1;
2280 #ifdef CONFIG_VNC_TLS
2281 if (acl && x509 && vs->tls.x509verify) {
2282 if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
2283 fprintf(stderr, "Failed to create x509 dname ACL\n");
2284 exit(1);
2287 #endif
2288 #ifdef CONFIG_VNC_SASL
2289 if (acl && sasl) {
2290 if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
2291 fprintf(stderr, "Failed to create username ACL\n");
2292 exit(1);
2295 #endif
2298 * Combinations we support here:
2300 * - no-auth (clear text, no auth)
2301 * - password (clear text, weak auth)
2302 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
2303 * - tls (encrypt, weak anonymous creds, no auth)
2304 * - tls + password (encrypt, weak anonymous creds, weak auth)
2305 * - tls + sasl (encrypt, weak anonymous creds, good auth)
2306 * - tls + x509 (encrypt, good x509 creds, no auth)
2307 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
2308 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
2310 * NB1. TLS is a stackable auth scheme.
2311 * NB2. the x509 schemes have option to validate a client cert dname
2313 if (password) {
2314 #ifdef CONFIG_VNC_TLS
2315 if (tls) {
2316 vs->auth = VNC_AUTH_VENCRYPT;
2317 if (x509) {
2318 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2319 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2320 } else {
2321 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2322 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2324 } else {
2325 #endif /* CONFIG_VNC_TLS */
2326 VNC_DEBUG("Initializing VNC server with password auth\n");
2327 vs->auth = VNC_AUTH_VNC;
2328 #ifdef CONFIG_VNC_TLS
2329 vs->subauth = VNC_AUTH_INVALID;
2331 #endif /* CONFIG_VNC_TLS */
2332 #ifdef CONFIG_VNC_SASL
2333 } else if (sasl) {
2334 #ifdef CONFIG_VNC_TLS
2335 if (tls) {
2336 vs->auth = VNC_AUTH_VENCRYPT;
2337 if (x509) {
2338 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
2339 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
2340 } else {
2341 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
2342 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
2344 } else {
2345 #endif /* CONFIG_VNC_TLS */
2346 VNC_DEBUG("Initializing VNC server with SASL auth\n");
2347 vs->auth = VNC_AUTH_SASL;
2348 #ifdef CONFIG_VNC_TLS
2349 vs->subauth = VNC_AUTH_INVALID;
2351 #endif /* CONFIG_VNC_TLS */
2352 #endif /* CONFIG_VNC_SASL */
2353 } else {
2354 #ifdef CONFIG_VNC_TLS
2355 if (tls) {
2356 vs->auth = VNC_AUTH_VENCRYPT;
2357 if (x509) {
2358 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2359 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2360 } else {
2361 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2362 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2364 } else {
2365 #endif
2366 VNC_DEBUG("Initializing VNC server with no auth\n");
2367 vs->auth = VNC_AUTH_NONE;
2368 #ifdef CONFIG_VNC_TLS
2369 vs->subauth = VNC_AUTH_INVALID;
2371 #endif
2374 #ifdef CONFIG_VNC_SASL
2375 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2376 fprintf(stderr, "Failed to initialize SASL auth %s",
2377 sasl_errstring(saslErr, NULL, NULL));
2378 free(vs->display);
2379 vs->display = NULL;
2380 return -1;
2382 #endif
2384 if (reverse) {
2385 /* connect to viewer */
2386 if (strncmp(display, "unix:", 5) == 0)
2387 vs->lsock = unix_connect(display+5);
2388 else
2389 vs->lsock = inet_connect(display, SOCK_STREAM);
2390 if (-1 == vs->lsock) {
2391 free(vs->display);
2392 vs->display = NULL;
2393 return -1;
2394 } else {
2395 int csock = vs->lsock;
2396 vs->lsock = -1;
2397 vnc_connect(vs, csock);
2399 return 0;
2401 } else {
2402 /* listen for connects */
2403 char *dpy;
2404 dpy = qemu_malloc(256);
2405 if (strncmp(display, "unix:", 5) == 0) {
2406 pstrcpy(dpy, 256, "unix:");
2407 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
2408 } else {
2409 vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
2411 if (-1 == vs->lsock) {
2412 free(dpy);
2413 return -1;
2414 } else {
2415 free(vs->display);
2416 vs->display = dpy;
2419 return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);