Temporary workaround for ppc on ppc
[qemu-kvm/fedora.git] / vnc.c
blob44a7746d59f7046f7086060fbe859fc94de0b6bd
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;
57 if ((err = getnameinfo((struct sockaddr *)sa, salen,
58 host, sizeof(host),
59 serv, sizeof(serv),
60 NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
61 VNC_DEBUG("Cannot resolve address %d: %s\n",
62 err, gai_strerror(err));
63 return NULL;
66 if (asprintf(&addr, format, host, serv) < 0)
67 return NULL;
69 return addr;
73 char *vnc_socket_local_addr(const char *format, int fd) {
74 struct sockaddr_storage sa;
75 socklen_t salen;
77 salen = sizeof(sa);
78 if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
79 return NULL;
81 return addr_to_string(format, &sa, salen);
85 char *vnc_socket_remote_addr(const char *format, int fd) {
86 struct sockaddr_storage sa;
87 socklen_t salen;
89 salen = sizeof(sa);
90 if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
91 return NULL;
93 return addr_to_string(format, &sa, salen);
96 static const char *vnc_auth_name(VncDisplay *vd) {
97 switch (vd->auth) {
98 case VNC_AUTH_INVALID:
99 return "invalid";
100 case VNC_AUTH_NONE:
101 return "none";
102 case VNC_AUTH_VNC:
103 return "vnc";
104 case VNC_AUTH_RA2:
105 return "ra2";
106 case VNC_AUTH_RA2NE:
107 return "ra2ne";
108 case VNC_AUTH_TIGHT:
109 return "tight";
110 case VNC_AUTH_ULTRA:
111 return "ultra";
112 case VNC_AUTH_TLS:
113 return "tls";
114 case VNC_AUTH_VENCRYPT:
115 #ifdef CONFIG_VNC_TLS
116 switch (vd->subauth) {
117 case VNC_AUTH_VENCRYPT_PLAIN:
118 return "vencrypt+plain";
119 case VNC_AUTH_VENCRYPT_TLSNONE:
120 return "vencrypt+tls+none";
121 case VNC_AUTH_VENCRYPT_TLSVNC:
122 return "vencrypt+tls+vnc";
123 case VNC_AUTH_VENCRYPT_TLSPLAIN:
124 return "vencrypt+tls+plain";
125 case VNC_AUTH_VENCRYPT_X509NONE:
126 return "vencrypt+x509+none";
127 case VNC_AUTH_VENCRYPT_X509VNC:
128 return "vencrypt+x509+vnc";
129 case VNC_AUTH_VENCRYPT_X509PLAIN:
130 return "vencrypt+x509+plain";
131 case VNC_AUTH_VENCRYPT_TLSSASL:
132 return "vencrypt+tls+sasl";
133 case VNC_AUTH_VENCRYPT_X509SASL:
134 return "vencrypt+x509+sasl";
135 default:
136 return "vencrypt";
138 #else
139 return "vencrypt";
140 #endif
141 case VNC_AUTH_SASL:
142 return "sasl";
144 return "unknown";
147 #define VNC_SOCKET_FORMAT_PRETTY "local %s:%s"
149 static void do_info_vnc_client(VncState *client)
151 char *clientAddr =
152 vnc_socket_remote_addr(" address: %s:%s\n",
153 client->csock);
154 if (!clientAddr)
155 return;
157 term_puts("Client:\n");
158 term_puts(clientAddr);
159 free(clientAddr);
161 #ifdef CONFIG_VNC_TLS
162 if (client->tls.session &&
163 client->tls.dname)
164 term_printf(" x509 dname: %s\n", client->tls.dname);
165 else
166 term_puts(" x509 dname: none\n");
167 #endif
168 #ifdef CONFIG_VNC_SASL
169 if (client->sasl.conn &&
170 client->sasl.username)
171 term_printf(" username: %s\n", client->sasl.username);
172 else
173 term_puts(" username: none\n");
174 #endif
177 void do_info_vnc(void)
179 if (vnc_display == NULL || vnc_display->display == NULL) {
180 term_printf("Server: disabled\n");
181 } else {
182 char *serverAddr = vnc_socket_local_addr(" address: %s:%s\n",
183 vnc_display->lsock);
185 if (!serverAddr)
186 return;
188 term_puts("Server:\n");
189 term_puts(serverAddr);
190 free(serverAddr);
191 term_printf(" auth: %s\n", vnc_auth_name(vnc_display));
193 if (vnc_display->clients) {
194 VncState *client = vnc_display->clients;
195 while (client) {
196 do_info_vnc_client(client);
197 client = client->next;
199 } else {
200 term_printf("Client: none\n");
205 static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
206 return (vs->features & (1 << feature));
209 /* TODO
210 1) Get the queue working for IO.
211 2) there is some weirdness when using the -S option (the screen is grey
212 and not totally invalidated
213 3) resolutions > 1024
216 static void vnc_update_client(void *opaque);
218 static void vnc_colordepth(VncState *vs);
220 static inline void vnc_set_bit(uint32_t *d, int k)
222 d[k >> 5] |= 1 << (k & 0x1f);
225 static inline void vnc_clear_bit(uint32_t *d, int k)
227 d[k >> 5] &= ~(1 << (k & 0x1f));
230 static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
232 int j;
234 j = 0;
235 while (n >= 32) {
236 d[j++] = -1;
237 n -= 32;
239 if (n > 0)
240 d[j++] = (1 << n) - 1;
241 while (j < nb_words)
242 d[j++] = 0;
245 static inline int vnc_get_bit(const uint32_t *d, int k)
247 return (d[k >> 5] >> (k & 0x1f)) & 1;
250 static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
251 int nb_words)
253 int i;
254 for(i = 0; i < nb_words; i++) {
255 if ((d1[i] & d2[i]) != 0)
256 return 1;
258 return 0;
261 static void vnc_update(VncState *vs, int x, int y, int w, int h)
263 int i;
265 h += y;
267 /* round x down to ensure the loop only spans one 16-pixel block per,
268 iteration. otherwise, if (x % 16) != 0, the last iteration may span
269 two 16-pixel blocks but we only mark the first as dirty
271 w += (x % 16);
272 x -= (x % 16);
274 x = MIN(x, vs->serverds.width);
275 y = MIN(y, vs->serverds.height);
276 w = MIN(x + w, vs->serverds.width) - x;
277 h = MIN(h, vs->serverds.height);
279 for (; y < h; y++)
280 for (i = 0; i < w; i += 16)
281 vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
284 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
286 VncDisplay *vd = ds->opaque;
287 VncState *vs = vd->clients;
288 while (vs != NULL) {
289 vnc_update(vs, x, y, w, h);
290 vs = vs->next;
294 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
295 int32_t encoding)
297 vnc_write_u16(vs, x);
298 vnc_write_u16(vs, y);
299 vnc_write_u16(vs, w);
300 vnc_write_u16(vs, h);
302 vnc_write_s32(vs, encoding);
305 void buffer_reserve(Buffer *buffer, size_t len)
307 if ((buffer->capacity - buffer->offset) < len) {
308 buffer->capacity += (len + 1024);
309 buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
310 if (buffer->buffer == NULL) {
311 fprintf(stderr, "vnc: out of memory\n");
312 exit(1);
317 int buffer_empty(Buffer *buffer)
319 return buffer->offset == 0;
322 uint8_t *buffer_end(Buffer *buffer)
324 return buffer->buffer + buffer->offset;
327 void buffer_reset(Buffer *buffer)
329 buffer->offset = 0;
332 void buffer_append(Buffer *buffer, const void *data, size_t len)
334 memcpy(buffer->buffer + buffer->offset, data, len);
335 buffer->offset += len;
338 static void vnc_resize(VncState *vs)
340 DisplayState *ds = vs->ds;
342 int size_changed;
344 vs->old_data = qemu_realloc(vs->old_data, ds_get_linesize(ds) * ds_get_height(ds));
346 if (vs->old_data == NULL) {
347 fprintf(stderr, "vnc: memory allocation failed\n");
348 exit(1);
351 if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
352 console_color_init(ds);
353 vnc_colordepth(vs);
354 size_changed = ds_get_width(ds) != vs->serverds.width ||
355 ds_get_height(ds) != vs->serverds.height;
356 vs->serverds = *(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);
368 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
369 memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
372 static void vnc_dpy_resize(DisplayState *ds)
374 VncDisplay *vd = ds->opaque;
375 VncState *vs = vd->clients;
376 while (vs != NULL) {
377 vnc_resize(vs);
378 vs = vs->next;
382 /* fastest code */
383 static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size)
385 vnc_write(vs, pixels, size);
388 /* slowest but generic code. */
389 static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
391 uint8_t r, g, b;
393 r = ((((v & vs->serverds.pf.rmask) >> vs->serverds.pf.rshift) << vs->clientds.pf.rbits) >>
394 vs->serverds.pf.rbits);
395 g = ((((v & vs->serverds.pf.gmask) >> vs->serverds.pf.gshift) << vs->clientds.pf.gbits) >>
396 vs->serverds.pf.gbits);
397 b = ((((v & vs->serverds.pf.bmask) >> vs->serverds.pf.bshift) << vs->clientds.pf.bbits) >>
398 vs->serverds.pf.bbits);
399 v = (r << vs->clientds.pf.rshift) |
400 (g << vs->clientds.pf.gshift) |
401 (b << vs->clientds.pf.bshift);
402 switch(vs->clientds.pf.bytes_per_pixel) {
403 case 1:
404 buf[0] = v;
405 break;
406 case 2:
407 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
408 buf[0] = v >> 8;
409 buf[1] = v;
410 } else {
411 buf[1] = v >> 8;
412 buf[0] = v;
414 break;
415 default:
416 case 4:
417 if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
418 buf[0] = v >> 24;
419 buf[1] = v >> 16;
420 buf[2] = v >> 8;
421 buf[3] = v;
422 } else {
423 buf[3] = v >> 24;
424 buf[2] = v >> 16;
425 buf[1] = v >> 8;
426 buf[0] = v;
428 break;
432 static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)
434 uint8_t buf[4];
436 if (vs->serverds.pf.bytes_per_pixel == 4) {
437 uint32_t *pixels = pixels1;
438 int n, i;
439 n = size >> 2;
440 for(i = 0; i < n; i++) {
441 vnc_convert_pixel(vs, buf, pixels[i]);
442 vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
444 } else if (vs->serverds.pf.bytes_per_pixel == 2) {
445 uint16_t *pixels = pixels1;
446 int n, i;
447 n = size >> 1;
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->serverds.pf.bytes_per_pixel == 1) {
453 uint8_t *pixels = pixels1;
454 int n, i;
455 n = size;
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 {
461 fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
465 static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)
467 int i;
468 uint8_t *row;
470 row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
471 for (i = 0; i < h; i++) {
472 vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));
473 row += ds_get_linesize(vs->ds);
477 static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
479 ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
480 ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
483 #define BPP 8
484 #include "vnchextile.h"
485 #undef BPP
487 #define BPP 16
488 #include "vnchextile.h"
489 #undef BPP
491 #define BPP 32
492 #include "vnchextile.h"
493 #undef BPP
495 #define GENERIC
496 #define BPP 8
497 #include "vnchextile.h"
498 #undef BPP
499 #undef GENERIC
501 #define GENERIC
502 #define BPP 16
503 #include "vnchextile.h"
504 #undef BPP
505 #undef GENERIC
507 #define GENERIC
508 #define BPP 32
509 #include "vnchextile.h"
510 #undef BPP
511 #undef GENERIC
513 static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, int h)
515 int i, j;
516 int has_fg, has_bg;
517 uint8_t *last_fg, *last_bg;
519 last_fg = (uint8_t *) qemu_malloc(vs->serverds.pf.bytes_per_pixel);
520 last_bg = (uint8_t *) qemu_malloc(vs->serverds.pf.bytes_per_pixel);
521 has_fg = has_bg = 0;
522 for (j = y; j < (y + h); j += 16) {
523 for (i = x; i < (x + w); i += 16) {
524 vs->send_hextile_tile(vs, i, j,
525 MIN(16, x + w - i), MIN(16, y + h - j),
526 last_bg, last_fg, &has_bg, &has_fg);
529 free(last_fg);
530 free(last_bg);
534 static void vnc_zlib_init(VncState *vs)
536 int i;
537 for (i=0; i<(sizeof(vs->zlib_stream) / sizeof(z_stream)); i++)
538 vs->zlib_stream[i].opaque = NULL;
541 static void vnc_zlib_start(VncState *vs)
543 buffer_reset(&vs->zlib);
545 // make the output buffer be the zlib buffer, so we can compress it later
546 vs->zlib_tmp = vs->output;
547 vs->output = vs->zlib;
550 static int vnc_zlib_stop(VncState *vs, int stream_id)
552 z_streamp zstream = &vs->zlib_stream[stream_id];
553 int previous_out;
555 // switch back to normal output/zlib buffers
556 vs->zlib = vs->output;
557 vs->output = vs->zlib_tmp;
559 // compress the zlib buffer
561 // initialize the stream
562 // XXX need one stream per session
563 if (zstream->opaque != vs) {
564 int err;
566 VNC_DEBUG("VNC: initializing zlib stream %d\n", stream_id);
567 VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
568 zstream->zalloc = Z_NULL;
569 zstream->zfree = Z_NULL;
571 err = deflateInit2(zstream, vs->tight_compression, Z_DEFLATED, MAX_WBITS,
572 MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
574 if (err != Z_OK) {
575 fprintf(stderr, "VNC: error initializing zlib\n");
576 return -1;
579 zstream->opaque = vs;
582 // XXX what to do if tight_compression changed in between?
584 // reserve memory in output buffer
585 buffer_reserve(&vs->output, vs->zlib.offset + 64);
587 // set pointers
588 zstream->next_in = vs->zlib.buffer;
589 zstream->avail_in = vs->zlib.offset;
590 zstream->next_out = vs->output.buffer + vs->output.offset;
591 zstream->avail_out = vs->output.capacity - vs->output.offset;
592 zstream->data_type = Z_BINARY;
593 previous_out = zstream->total_out;
595 // start encoding
596 if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
597 fprintf(stderr, "VNC: error during zlib compression\n");
598 return -1;
601 vs->output.offset = vs->output.capacity - zstream->avail_out;
602 return zstream->total_out - previous_out;
605 static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)
607 int old_offset, new_offset, bytes_written;
609 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
611 // remember where we put in the follow-up size
612 old_offset = vs->output.offset;
613 vnc_write_s32(vs, 0);
615 // compress the stream
616 vnc_zlib_start(vs);
617 send_framebuffer_update_raw(vs, x, y, w, h);
618 bytes_written = vnc_zlib_stop(vs, 0);
620 if (bytes_written == -1)
621 return;
623 // hack in the size
624 new_offset = vs->output.offset;
625 vs->output.offset = old_offset;
626 vnc_write_u32(vs, bytes_written);
627 vs->output.offset = new_offset;
630 static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
632 switch(vs->vnc_encoding) {
633 case VNC_ENCODING_ZLIB:
634 send_framebuffer_update_zlib(vs, x, y, w, h);
635 break;
636 case VNC_ENCODING_HEXTILE:
637 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
638 send_framebuffer_update_hextile(vs, x, y, w, h);
639 break;
640 default:
641 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
642 send_framebuffer_update_raw(vs, x, y, w, h);
643 break;
647 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
649 vnc_update_client(vs);
651 vnc_write_u8(vs, 0); /* msg id */
652 vnc_write_u8(vs, 0);
653 vnc_write_u16(vs, 1); /* number of rects */
654 vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
655 vnc_write_u16(vs, src_x);
656 vnc_write_u16(vs, src_y);
657 vnc_flush(vs);
660 static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
662 VncDisplay *vd = ds->opaque;
663 VncState *vs = vd->clients;
664 while (vs != NULL) {
665 if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
666 vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
667 else /* TODO */
668 vnc_update(vs, dst_x, dst_y, w, h);
669 vs = vs->next;
673 static int find_dirty_height(VncState *vs, int y, int last_x, int x)
675 int h;
677 for (h = 1; h < (vs->serverds.height - y); h++) {
678 int tmp_x;
679 if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
680 break;
681 for (tmp_x = last_x; tmp_x < x; tmp_x++)
682 vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
685 return h;
688 static void vnc_update_client(void *opaque)
690 VncState *vs = opaque;
691 if (vs->need_update && vs->csock != -1) {
692 int y;
693 uint8_t *row;
694 char *old_row;
695 uint32_t width_mask[VNC_DIRTY_WORDS];
696 int n_rectangles;
697 int saved_offset;
698 int has_dirty = 0;
700 vga_hw_update();
702 vnc_set_bits(width_mask, (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
704 /* Walk through the dirty map and eliminate tiles that
705 really aren't dirty */
706 row = ds_get_data(vs->ds);
707 old_row = vs->old_data;
709 for (y = 0; y < ds_get_height(vs->ds); y++) {
710 if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
711 int x;
712 uint8_t *ptr;
713 char *old_ptr;
715 ptr = row;
716 old_ptr = (char*)old_row;
718 for (x = 0; x < ds_get_width(vs->ds); x += 16) {
719 if (memcmp(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds)) == 0) {
720 vnc_clear_bit(vs->dirty_row[y], (x / 16));
721 } else {
722 has_dirty = 1;
723 memcpy(old_ptr, ptr, 16 * ds_get_bytes_per_pixel(vs->ds));
726 ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
727 old_ptr += 16 * ds_get_bytes_per_pixel(vs->ds);
731 row += ds_get_linesize(vs->ds);
732 old_row += ds_get_linesize(vs->ds);
735 if (!has_dirty && !vs->audio_cap) {
736 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
737 return;
740 /* Count rectangles */
741 n_rectangles = 0;
742 vnc_write_u8(vs, 0); /* msg id */
743 vnc_write_u8(vs, 0);
744 saved_offset = vs->output.offset;
745 vnc_write_u16(vs, 0);
747 for (y = 0; y < vs->serverds.height; y++) {
748 int x;
749 int last_x = -1;
750 for (x = 0; x < vs->serverds.width / 16; x++) {
751 if (vnc_get_bit(vs->dirty_row[y], x)) {
752 if (last_x == -1) {
753 last_x = x;
755 vnc_clear_bit(vs->dirty_row[y], x);
756 } else {
757 if (last_x != -1) {
758 int h = find_dirty_height(vs, y, last_x, x);
759 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
760 n_rectangles++;
762 last_x = -1;
765 if (last_x != -1) {
766 int h = find_dirty_height(vs, y, last_x, x);
767 send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h);
768 n_rectangles++;
771 vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
772 vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
773 vnc_flush(vs);
777 if (vs->csock != -1) {
778 qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
783 /* audio */
784 static void audio_capture_notify(void *opaque, audcnotification_e cmd)
786 VncState *vs = opaque;
788 switch (cmd) {
789 case AUD_CNOTIFY_DISABLE:
790 vnc_write_u8(vs, 255);
791 vnc_write_u8(vs, 1);
792 vnc_write_u16(vs, 0);
793 vnc_flush(vs);
794 break;
796 case AUD_CNOTIFY_ENABLE:
797 vnc_write_u8(vs, 255);
798 vnc_write_u8(vs, 1);
799 vnc_write_u16(vs, 1);
800 vnc_flush(vs);
801 break;
805 static void audio_capture_destroy(void *opaque)
809 static void audio_capture(void *opaque, void *buf, int size)
811 VncState *vs = opaque;
813 vnc_write_u8(vs, 255);
814 vnc_write_u8(vs, 1);
815 vnc_write_u16(vs, 2);
816 vnc_write_u32(vs, size);
817 vnc_write(vs, buf, size);
818 vnc_flush(vs);
821 static void audio_add(VncState *vs)
823 struct audio_capture_ops ops;
825 if (vs->audio_cap) {
826 term_printf ("audio already running\n");
827 return;
830 ops.notify = audio_capture_notify;
831 ops.destroy = audio_capture_destroy;
832 ops.capture = audio_capture;
834 vs->audio_cap = AUD_add_capture(NULL, &vs->as, &ops, vs);
835 if (!vs->audio_cap) {
836 term_printf ("Failed to add audio capture\n");
840 static void audio_del(VncState *vs)
842 if (vs->audio_cap) {
843 AUD_del_capture(vs->audio_cap, vs);
844 vs->audio_cap = NULL;
849 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
851 if (ret == 0 || ret == -1) {
852 if (ret == -1) {
853 switch (last_errno) {
854 case EINTR:
855 case EAGAIN:
856 #ifdef _WIN32
857 case WSAEWOULDBLOCK:
858 #endif
859 return 0;
860 default:
861 break;
865 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
866 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
867 closesocket(vs->csock);
868 qemu_del_timer(vs->timer);
869 qemu_free_timer(vs->timer);
870 if (vs->input.buffer) qemu_free(vs->input.buffer);
871 if (vs->output.buffer) qemu_free(vs->output.buffer);
872 #ifdef CONFIG_VNC_TLS
873 vnc_tls_client_cleanup(vs);
874 #endif /* CONFIG_VNC_TLS */
875 #ifdef CONFIG_VNC_SASL
876 vnc_sasl_client_cleanup(vs);
877 #endif /* CONFIG_VNC_SASL */
878 audio_del(vs);
880 VncState *p, *parent = NULL;
881 for (p = vs->vd->clients; p != NULL; p = p->next) {
882 if (p == vs) {
883 if (parent)
884 parent->next = p->next;
885 else
886 vs->vd->clients = p->next;
887 break;
889 parent = p;
891 if (!vs->vd->clients)
892 dcl->idle = 1;
894 qemu_free(vs->old_data);
895 qemu_free(vs);
897 return 0;
899 return ret;
903 void vnc_client_error(VncState *vs)
905 vnc_client_io_error(vs, -1, EINVAL);
910 * Called to write a chunk of data to the client socket. The data may
911 * be the raw data, or may have already been encoded by SASL.
912 * The data will be written either straight onto the socket, or
913 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
915 * NB, it is theoretically possible to have 2 layers of encryption,
916 * both SASL, and this TLS layer. It is highly unlikely in practice
917 * though, since SASL encryption will typically be a no-op if TLS
918 * is active
920 * Returns the number of bytes written, which may be less than
921 * the requested 'datalen' if the socket would block. Returns
922 * -1 on error, and disconnects the client socket.
924 long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
926 long ret;
927 #ifdef CONFIG_VNC_TLS
928 if (vs->tls.session) {
929 ret = gnutls_write(vs->tls.session, data, datalen);
930 if (ret < 0) {
931 if (ret == GNUTLS_E_AGAIN)
932 errno = EAGAIN;
933 else
934 errno = EIO;
935 ret = -1;
937 } else
938 #endif /* CONFIG_VNC_TLS */
939 ret = send(vs->csock, data, datalen, 0);
940 VNC_DEBUG("Wrote wire %p %d -> %ld\n", data, datalen, ret);
941 return vnc_client_io_error(vs, ret, socket_error());
946 * Called to write buffered data to the client socket, when not
947 * using any SASL SSF encryption layers. Will write as much data
948 * as possible without blocking. If all buffered data is written,
949 * will switch the FD poll() handler back to read monitoring.
951 * Returns the number of bytes written, which may be less than
952 * the buffered output data if the socket would block. Returns
953 * -1 on error, and disconnects the client socket.
955 static long vnc_client_write_plain(VncState *vs)
957 long ret;
959 #ifdef CONFIG_VNC_SASL
960 VNC_DEBUG("Write Plain: Pending output %p size %d offset %d. Wait SSF %d\n",
961 vs->output.buffer, vs->output.capacity, vs->output.offset,
962 vs->sasl.waitWriteSSF);
964 if (vs->sasl.conn &&
965 vs->sasl.runSSF &&
966 vs->sasl.waitWriteSSF) {
967 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
968 if (ret)
969 vs->sasl.waitWriteSSF -= ret;
970 } else
971 #endif /* CONFIG_VNC_SASL */
972 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
973 if (!ret)
974 return 0;
976 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
977 vs->output.offset -= ret;
979 if (vs->output.offset == 0) {
980 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
983 return ret;
988 * First function called whenever there is data to be written to
989 * the client socket. Will delegate actual work according to whether
990 * SASL SSF layers are enabled (thus requiring encryption calls)
992 void vnc_client_write(void *opaque)
994 long ret;
995 VncState *vs = opaque;
997 #ifdef CONFIG_VNC_SASL
998 if (vs->sasl.conn &&
999 vs->sasl.runSSF &&
1000 !vs->sasl.waitWriteSSF)
1001 ret = vnc_client_write_sasl(vs);
1002 else
1003 #endif /* CONFIG_VNC_SASL */
1004 ret = vnc_client_write_plain(vs);
1007 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1009 vs->read_handler = func;
1010 vs->read_handler_expect = expecting;
1015 * Called to read a chunk of data from the client socket. The data may
1016 * be the raw data, or may need to be further decoded by SASL.
1017 * The data will be read either straight from to the socket, or
1018 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1020 * NB, it is theoretically possible to have 2 layers of encryption,
1021 * both SASL, and this TLS layer. It is highly unlikely in practice
1022 * though, since SASL encryption will typically be a no-op if TLS
1023 * is active
1025 * Returns the number of bytes read, which may be less than
1026 * the requested 'datalen' if the socket would block. Returns
1027 * -1 on error, and disconnects the client socket.
1029 long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1031 long ret;
1032 #ifdef CONFIG_VNC_TLS
1033 if (vs->tls.session) {
1034 ret = gnutls_read(vs->tls.session, data, datalen);
1035 if (ret < 0) {
1036 if (ret == GNUTLS_E_AGAIN)
1037 errno = EAGAIN;
1038 else
1039 errno = EIO;
1040 ret = -1;
1042 } else
1043 #endif /* CONFIG_VNC_TLS */
1044 ret = recv(vs->csock, data, datalen, 0);
1045 VNC_DEBUG("Read wire %p %d -> %ld\n", data, datalen, ret);
1046 return vnc_client_io_error(vs, ret, socket_error());
1051 * Called to read data from the client socket to the input buffer,
1052 * when not using any SASL SSF encryption layers. Will read as much
1053 * data as possible without blocking.
1055 * Returns the number of bytes read. Returns -1 on error, and
1056 * disconnects the client socket.
1058 static long vnc_client_read_plain(VncState *vs)
1060 int ret;
1061 VNC_DEBUG("Read plain %p size %d offset %d\n",
1062 vs->input.buffer, vs->input.capacity, vs->input.offset);
1063 buffer_reserve(&vs->input, 4096);
1064 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1065 if (!ret)
1066 return 0;
1067 vs->input.offset += ret;
1068 return ret;
1073 * First function called whenever there is more data to be read from
1074 * the client socket. Will delegate actual work according to whether
1075 * SASL SSF layers are enabled (thus requiring decryption calls)
1077 void vnc_client_read(void *opaque)
1079 VncState *vs = opaque;
1080 long ret;
1082 #ifdef CONFIG_VNC_SASL
1083 if (vs->sasl.conn && vs->sasl.runSSF)
1084 ret = vnc_client_read_sasl(vs);
1085 else
1086 #endif /* CONFIG_VNC_SASL */
1087 ret = vnc_client_read_plain(vs);
1088 if (!ret)
1089 return;
1091 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1092 size_t len = vs->read_handler_expect;
1093 int ret;
1095 ret = vs->read_handler(vs, vs->input.buffer, len);
1096 if (vs->csock == -1)
1097 return;
1099 if (!ret) {
1100 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
1101 vs->input.offset -= len;
1102 } else {
1103 vs->read_handler_expect = ret;
1108 void vnc_write(VncState *vs, const void *data, size_t len)
1110 buffer_reserve(&vs->output, len);
1112 if (buffer_empty(&vs->output)) {
1113 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1116 buffer_append(&vs->output, data, len);
1119 void vnc_write_s32(VncState *vs, int32_t value)
1121 vnc_write_u32(vs, *(uint32_t *)&value);
1124 void vnc_write_u32(VncState *vs, uint32_t value)
1126 uint8_t buf[4];
1128 buf[0] = (value >> 24) & 0xFF;
1129 buf[1] = (value >> 16) & 0xFF;
1130 buf[2] = (value >> 8) & 0xFF;
1131 buf[3] = value & 0xFF;
1133 vnc_write(vs, buf, 4);
1136 void vnc_write_u16(VncState *vs, uint16_t value)
1138 uint8_t buf[2];
1140 buf[0] = (value >> 8) & 0xFF;
1141 buf[1] = value & 0xFF;
1143 vnc_write(vs, buf, 2);
1146 void vnc_write_u8(VncState *vs, uint8_t value)
1148 vnc_write(vs, (char *)&value, 1);
1151 void vnc_flush(VncState *vs)
1153 if (vs->output.offset)
1154 vnc_client_write(vs);
1157 uint8_t read_u8(uint8_t *data, size_t offset)
1159 return data[offset];
1162 uint16_t read_u16(uint8_t *data, size_t offset)
1164 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1167 int32_t read_s32(uint8_t *data, size_t offset)
1169 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1170 (data[offset + 2] << 8) | data[offset + 3]);
1173 uint32_t read_u32(uint8_t *data, size_t offset)
1175 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1176 (data[offset + 2] << 8) | data[offset + 3]);
1179 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1183 static void check_pointer_type_change(VncState *vs, int absolute)
1185 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1186 vnc_write_u8(vs, 0);
1187 vnc_write_u8(vs, 0);
1188 vnc_write_u16(vs, 1);
1189 vnc_framebuffer_update(vs, absolute, 0,
1190 ds_get_width(vs->ds), ds_get_height(vs->ds),
1191 VNC_ENCODING_POINTER_TYPE_CHANGE);
1192 vnc_flush(vs);
1194 vs->absolute = absolute;
1197 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1199 int buttons = 0;
1200 int dz = 0;
1202 if (button_mask & 0x01)
1203 buttons |= MOUSE_EVENT_LBUTTON;
1204 if (button_mask & 0x02)
1205 buttons |= MOUSE_EVENT_MBUTTON;
1206 if (button_mask & 0x04)
1207 buttons |= MOUSE_EVENT_RBUTTON;
1208 if (button_mask & 0x08)
1209 dz = -1;
1210 if (button_mask & 0x10)
1211 dz = 1;
1213 if (vs->absolute) {
1214 kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
1215 y * 0x7FFF / (ds_get_height(vs->ds) - 1),
1216 dz, buttons);
1217 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1218 x -= 0x7FFF;
1219 y -= 0x7FFF;
1221 kbd_mouse_event(x, y, dz, buttons);
1222 } else {
1223 if (vs->last_x != -1)
1224 kbd_mouse_event(x - vs->last_x,
1225 y - vs->last_y,
1226 dz, buttons);
1227 vs->last_x = x;
1228 vs->last_y = y;
1231 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1234 static void reset_keys(VncState *vs)
1236 int i;
1237 for(i = 0; i < 256; i++) {
1238 if (vs->modifiers_state[i]) {
1239 if (i & 0x80)
1240 kbd_put_keycode(0xe0);
1241 kbd_put_keycode(i | 0x80);
1242 vs->modifiers_state[i] = 0;
1247 static void press_key(VncState *vs, int keysym)
1249 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
1250 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
1253 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1255 /* QEMU console switch */
1256 switch(keycode) {
1257 case 0x2a: /* Left Shift */
1258 case 0x36: /* Right Shift */
1259 case 0x1d: /* Left CTRL */
1260 case 0x9d: /* Right CTRL */
1261 case 0x38: /* Left ALT */
1262 case 0xb8: /* Right ALT */
1263 if (down)
1264 vs->modifiers_state[keycode] = 1;
1265 else
1266 vs->modifiers_state[keycode] = 0;
1267 break;
1268 case 0x02 ... 0x0a: /* '1' to '9' keys */
1269 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1270 /* Reset the modifiers sent to the current console */
1271 reset_keys(vs);
1272 console_select(keycode - 0x02);
1273 return;
1275 break;
1276 case 0x3a: /* CapsLock */
1277 case 0x45: /* NumLock */
1278 if (!down)
1279 vs->modifiers_state[keycode] ^= 1;
1280 break;
1283 if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1284 /* If the numlock state needs to change then simulate an additional
1285 keypress before sending this one. This will happen if the user
1286 toggles numlock away from the VNC window.
1288 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1289 if (!vs->modifiers_state[0x45]) {
1290 vs->modifiers_state[0x45] = 1;
1291 press_key(vs, 0xff7f);
1293 } else {
1294 if (vs->modifiers_state[0x45]) {
1295 vs->modifiers_state[0x45] = 0;
1296 press_key(vs, 0xff7f);
1301 if (is_graphic_console()) {
1302 if (keycode & 0x80)
1303 kbd_put_keycode(0xe0);
1304 if (down)
1305 kbd_put_keycode(keycode & 0x7f);
1306 else
1307 kbd_put_keycode(keycode | 0x80);
1308 } else {
1309 /* QEMU console emulation */
1310 if (down) {
1311 switch (keycode) {
1312 case 0x2a: /* Left Shift */
1313 case 0x36: /* Right Shift */
1314 case 0x1d: /* Left CTRL */
1315 case 0x9d: /* Right CTRL */
1316 case 0x38: /* Left ALT */
1317 case 0xb8: /* Right ALT */
1318 break;
1319 case 0xc8:
1320 case 0x48:
1321 kbd_put_keysym(QEMU_KEY_UP);
1322 break;
1323 case 0xd0:
1324 case 0x50:
1325 kbd_put_keysym(QEMU_KEY_DOWN);
1326 break;
1327 case 0xcb:
1328 case 0x4b:
1329 kbd_put_keysym(QEMU_KEY_LEFT);
1330 break;
1331 case 0xcd:
1332 case 0x4d:
1333 kbd_put_keysym(QEMU_KEY_RIGHT);
1334 break;
1335 case 0xd3:
1336 case 0x53:
1337 kbd_put_keysym(QEMU_KEY_DELETE);
1338 break;
1339 case 0xc7:
1340 case 0x47:
1341 kbd_put_keysym(QEMU_KEY_HOME);
1342 break;
1343 case 0xcf:
1344 case 0x4f:
1345 kbd_put_keysym(QEMU_KEY_END);
1346 break;
1347 case 0xc9:
1348 case 0x49:
1349 kbd_put_keysym(QEMU_KEY_PAGEUP);
1350 break;
1351 case 0xd1:
1352 case 0x51:
1353 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1354 break;
1355 default:
1356 kbd_put_keysym(sym);
1357 break;
1363 static void key_event(VncState *vs, int down, uint32_t sym)
1365 int keycode;
1367 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1368 sym = sym - 'A' + 'a';
1370 keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
1371 do_key_event(vs, down, keycode, sym);
1374 static void ext_key_event(VncState *vs, int down,
1375 uint32_t sym, uint16_t keycode)
1377 /* if the user specifies a keyboard layout, always use it */
1378 if (keyboard_layout)
1379 key_event(vs, down, sym);
1380 else
1381 do_key_event(vs, down, keycode, sym);
1384 static void framebuffer_update_request(VncState *vs, int incremental,
1385 int x_position, int y_position,
1386 int w, int h)
1388 if (x_position > ds_get_width(vs->ds))
1389 x_position = ds_get_width(vs->ds);
1390 if (y_position > ds_get_height(vs->ds))
1391 y_position = ds_get_height(vs->ds);
1392 if (x_position + w >= ds_get_width(vs->ds))
1393 w = ds_get_width(vs->ds) - x_position;
1394 if (y_position + h >= ds_get_height(vs->ds))
1395 h = ds_get_height(vs->ds) - y_position;
1397 int i;
1398 vs->need_update = 1;
1399 if (!incremental) {
1400 char *old_row = vs->old_data + y_position * ds_get_linesize(vs->ds);
1402 for (i = 0; i < h; i++) {
1403 vnc_set_bits(vs->dirty_row[y_position + i],
1404 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1405 memset(old_row, 42, ds_get_width(vs->ds) * ds_get_bytes_per_pixel(vs->ds));
1406 old_row += ds_get_linesize(vs->ds);
1411 static void send_ext_key_event_ack(VncState *vs)
1413 vnc_write_u8(vs, 0);
1414 vnc_write_u8(vs, 0);
1415 vnc_write_u16(vs, 1);
1416 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1417 VNC_ENCODING_EXT_KEY_EVENT);
1418 vnc_flush(vs);
1421 static void send_ext_audio_ack(VncState *vs)
1423 vnc_write_u8(vs, 0);
1424 vnc_write_u8(vs, 0);
1425 vnc_write_u16(vs, 1);
1426 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1427 VNC_ENCODING_AUDIO);
1428 vnc_flush(vs);
1431 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1433 int i;
1434 unsigned int enc = 0;
1436 vnc_zlib_init(vs);
1437 vs->features = 0;
1438 vs->vnc_encoding = 0;
1439 vs->tight_compression = 9;
1440 vs->tight_quality = 9;
1441 vs->absolute = -1;
1443 for (i = n_encodings - 1; i >= 0; i--) {
1444 enc = encodings[i];
1445 switch (enc) {
1446 case VNC_ENCODING_RAW:
1447 vs->vnc_encoding = enc;
1448 break;
1449 case VNC_ENCODING_COPYRECT:
1450 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1451 break;
1452 case VNC_ENCODING_HEXTILE:
1453 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1454 vs->vnc_encoding = enc;
1455 break;
1456 case VNC_ENCODING_ZLIB:
1457 vs->features |= VNC_FEATURE_ZLIB_MASK;
1458 vs->vnc_encoding = enc;
1459 break;
1460 case VNC_ENCODING_DESKTOPRESIZE:
1461 vs->features |= VNC_FEATURE_RESIZE_MASK;
1462 break;
1463 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1464 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1465 break;
1466 case VNC_ENCODING_EXT_KEY_EVENT:
1467 send_ext_key_event_ack(vs);
1468 break;
1469 case VNC_ENCODING_AUDIO:
1470 send_ext_audio_ack(vs);
1471 break;
1472 case VNC_ENCODING_WMVi:
1473 vs->features |= VNC_FEATURE_WMVI_MASK;
1474 break;
1475 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1476 vs->tight_compression = (enc & 0x0F);
1477 break;
1478 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1479 vs->tight_quality = (enc & 0x0F);
1480 break;
1481 default:
1482 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1483 break;
1487 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1490 static void set_pixel_conversion(VncState *vs)
1492 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1493 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1494 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1495 vs->write_pixels = vnc_write_pixels_copy;
1496 switch (vs->ds->surface->pf.bits_per_pixel) {
1497 case 8:
1498 vs->send_hextile_tile = send_hextile_tile_8;
1499 break;
1500 case 16:
1501 vs->send_hextile_tile = send_hextile_tile_16;
1502 break;
1503 case 32:
1504 vs->send_hextile_tile = send_hextile_tile_32;
1505 break;
1507 } else {
1508 vs->write_pixels = vnc_write_pixels_generic;
1509 switch (vs->ds->surface->pf.bits_per_pixel) {
1510 case 8:
1511 vs->send_hextile_tile = send_hextile_tile_generic_8;
1512 break;
1513 case 16:
1514 vs->send_hextile_tile = send_hextile_tile_generic_16;
1515 break;
1516 case 32:
1517 vs->send_hextile_tile = send_hextile_tile_generic_32;
1518 break;
1523 static void set_pixel_format(VncState *vs,
1524 int bits_per_pixel, int depth,
1525 int big_endian_flag, int true_color_flag,
1526 int red_max, int green_max, int blue_max,
1527 int red_shift, int green_shift, int blue_shift)
1529 if (!true_color_flag) {
1530 vnc_client_error(vs);
1531 return;
1534 vs->clientds = vs->serverds;
1535 vs->clientds.pf.rmax = red_max;
1536 count_bits(vs->clientds.pf.rbits, red_max);
1537 vs->clientds.pf.rshift = red_shift;
1538 vs->clientds.pf.rmask = red_max << red_shift;
1539 vs->clientds.pf.gmax = green_max;
1540 count_bits(vs->clientds.pf.gbits, green_max);
1541 vs->clientds.pf.gshift = green_shift;
1542 vs->clientds.pf.gmask = green_max << green_shift;
1543 vs->clientds.pf.bmax = blue_max;
1544 count_bits(vs->clientds.pf.bbits, blue_max);
1545 vs->clientds.pf.bshift = blue_shift;
1546 vs->clientds.pf.bmask = blue_max << blue_shift;
1547 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1548 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1549 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1550 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1552 set_pixel_conversion(vs);
1554 vga_hw_invalidate();
1555 vga_hw_update();
1558 static void pixel_format_message (VncState *vs) {
1559 char pad[3] = { 0, 0, 0 };
1561 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1562 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
1564 #ifdef WORDS_BIGENDIAN
1565 vnc_write_u8(vs, 1); /* big-endian-flag */
1566 #else
1567 vnc_write_u8(vs, 0); /* big-endian-flag */
1568 #endif
1569 vnc_write_u8(vs, 1); /* true-color-flag */
1570 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1571 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1572 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1573 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1574 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1575 vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
1576 if (vs->ds->surface->pf.bits_per_pixel == 32)
1577 vs->send_hextile_tile = send_hextile_tile_32;
1578 else if (vs->ds->surface->pf.bits_per_pixel == 16)
1579 vs->send_hextile_tile = send_hextile_tile_16;
1580 else if (vs->ds->surface->pf.bits_per_pixel == 8)
1581 vs->send_hextile_tile = send_hextile_tile_8;
1582 vs->clientds = *(vs->ds->surface);
1583 vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
1584 vs->write_pixels = vnc_write_pixels_copy;
1586 vnc_write(vs, pad, 3); /* padding */
1589 static void vnc_dpy_setdata(DisplayState *ds)
1591 /* We don't have to do anything */
1594 static void vnc_colordepth(VncState *vs)
1596 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
1597 /* Sending a WMVi message to notify the client*/
1598 vnc_write_u8(vs, 0); /* msg id */
1599 vnc_write_u8(vs, 0);
1600 vnc_write_u16(vs, 1); /* number of rects */
1601 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
1602 ds_get_height(vs->ds), VNC_ENCODING_WMVi);
1603 pixel_format_message(vs);
1604 vnc_flush(vs);
1605 } else {
1606 set_pixel_conversion(vs);
1610 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1612 int i;
1613 uint16_t limit;
1615 switch (data[0]) {
1616 case 0:
1617 if (len == 1)
1618 return 20;
1620 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1621 read_u8(data, 6), read_u8(data, 7),
1622 read_u16(data, 8), read_u16(data, 10),
1623 read_u16(data, 12), read_u8(data, 14),
1624 read_u8(data, 15), read_u8(data, 16));
1625 break;
1626 case 2:
1627 if (len == 1)
1628 return 4;
1630 if (len == 4) {
1631 limit = read_u16(data, 2);
1632 if (limit > 0)
1633 return 4 + (limit * 4);
1634 } else
1635 limit = read_u16(data, 2);
1637 for (i = 0; i < limit; i++) {
1638 int32_t val = read_s32(data, 4 + (i * 4));
1639 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1642 set_encodings(vs, (int32_t *)(data + 4), limit);
1643 break;
1644 case 3:
1645 if (len == 1)
1646 return 10;
1648 framebuffer_update_request(vs,
1649 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1650 read_u16(data, 6), read_u16(data, 8));
1651 break;
1652 case 4:
1653 if (len == 1)
1654 return 8;
1656 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1657 break;
1658 case 5:
1659 if (len == 1)
1660 return 6;
1662 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1663 break;
1664 case 6:
1665 if (len == 1)
1666 return 8;
1668 if (len == 8) {
1669 uint32_t dlen = read_u32(data, 4);
1670 if (dlen > 0)
1671 return 8 + dlen;
1674 client_cut_text(vs, read_u32(data, 4), data + 8);
1675 break;
1676 case 255:
1677 if (len == 1)
1678 return 2;
1680 switch (read_u8(data, 1)) {
1681 case 0:
1682 if (len == 2)
1683 return 12;
1685 ext_key_event(vs, read_u16(data, 2),
1686 read_u32(data, 4), read_u32(data, 8));
1687 break;
1688 case 1:
1689 if (len == 2)
1690 return 4;
1692 switch (read_u16 (data, 2)) {
1693 case 0:
1694 audio_add(vs);
1695 break;
1696 case 1:
1697 audio_del(vs);
1698 break;
1699 case 2:
1700 if (len == 4)
1701 return 10;
1702 switch (read_u8(data, 4)) {
1703 case 0: vs->as.fmt = AUD_FMT_U8; break;
1704 case 1: vs->as.fmt = AUD_FMT_S8; break;
1705 case 2: vs->as.fmt = AUD_FMT_U16; break;
1706 case 3: vs->as.fmt = AUD_FMT_S16; break;
1707 case 4: vs->as.fmt = AUD_FMT_U32; break;
1708 case 5: vs->as.fmt = AUD_FMT_S32; break;
1709 default:
1710 printf("Invalid audio format %d\n", read_u8(data, 4));
1711 vnc_client_error(vs);
1712 break;
1714 vs->as.nchannels = read_u8(data, 5);
1715 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
1716 printf("Invalid audio channel coount %d\n",
1717 read_u8(data, 5));
1718 vnc_client_error(vs);
1719 break;
1721 vs->as.freq = read_u32(data, 6);
1722 break;
1723 default:
1724 printf ("Invalid audio message %d\n", read_u8(data, 4));
1725 vnc_client_error(vs);
1726 break;
1728 break;
1730 default:
1731 printf("Msg: %d\n", read_u16(data, 0));
1732 vnc_client_error(vs);
1733 break;
1735 break;
1736 default:
1737 printf("Msg: %d\n", data[0]);
1738 vnc_client_error(vs);
1739 break;
1742 vnc_read_when(vs, protocol_client_msg, 1);
1743 return 0;
1746 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1748 char buf[1024];
1749 int size;
1751 vnc_write_u16(vs, ds_get_width(vs->ds));
1752 vnc_write_u16(vs, ds_get_height(vs->ds));
1754 pixel_format_message(vs);
1756 if (qemu_name)
1757 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1758 else
1759 size = snprintf(buf, sizeof(buf), "QEMU");
1761 vnc_write_u32(vs, size);
1762 vnc_write(vs, buf, size);
1763 vnc_flush(vs);
1765 vnc_read_when(vs, protocol_client_msg, 1);
1767 return 0;
1770 void start_client_init(VncState *vs)
1772 vnc_read_when(vs, protocol_client_init, 1);
1775 static void make_challenge(VncState *vs)
1777 int i;
1779 srand(time(NULL)+getpid()+getpid()*987654+rand());
1781 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1782 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1785 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1787 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1788 int i, j, pwlen;
1789 unsigned char key[8];
1791 if (!vs->vd->password || !vs->vd->password[0]) {
1792 VNC_DEBUG("No password configured on server");
1793 vnc_write_u32(vs, 1); /* Reject auth */
1794 if (vs->minor >= 8) {
1795 static const char err[] = "Authentication failed";
1796 vnc_write_u32(vs, sizeof(err));
1797 vnc_write(vs, err, sizeof(err));
1799 vnc_flush(vs);
1800 vnc_client_error(vs);
1801 return 0;
1804 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1806 /* Calculate the expected challenge response */
1807 pwlen = strlen(vs->vd->password);
1808 for (i=0; i<sizeof(key); i++)
1809 key[i] = i<pwlen ? vs->vd->password[i] : 0;
1810 deskey(key, EN0);
1811 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1812 des(response+j, response+j);
1814 /* Compare expected vs actual challenge response */
1815 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1816 VNC_DEBUG("Client challenge reponse did not match\n");
1817 vnc_write_u32(vs, 1); /* Reject auth */
1818 if (vs->minor >= 8) {
1819 static const char err[] = "Authentication failed";
1820 vnc_write_u32(vs, sizeof(err));
1821 vnc_write(vs, err, sizeof(err));
1823 vnc_flush(vs);
1824 vnc_client_error(vs);
1825 } else {
1826 VNC_DEBUG("Accepting VNC challenge response\n");
1827 vnc_write_u32(vs, 0); /* Accept auth */
1828 vnc_flush(vs);
1830 start_client_init(vs);
1832 return 0;
1835 void start_auth_vnc(VncState *vs)
1837 make_challenge(vs);
1838 /* Send client a 'random' challenge */
1839 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1840 vnc_flush(vs);
1842 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1846 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1848 /* We only advertise 1 auth scheme at a time, so client
1849 * must pick the one we sent. Verify this */
1850 if (data[0] != vs->vd->auth) { /* Reject auth */
1851 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
1852 vnc_write_u32(vs, 1);
1853 if (vs->minor >= 8) {
1854 static const char err[] = "Authentication failed";
1855 vnc_write_u32(vs, sizeof(err));
1856 vnc_write(vs, err, sizeof(err));
1858 vnc_client_error(vs);
1859 } else { /* Accept requested auth */
1860 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1861 switch (vs->vd->auth) {
1862 case VNC_AUTH_NONE:
1863 VNC_DEBUG("Accept auth none\n");
1864 if (vs->minor >= 8) {
1865 vnc_write_u32(vs, 0); /* Accept auth completion */
1866 vnc_flush(vs);
1868 start_client_init(vs);
1869 break;
1871 case VNC_AUTH_VNC:
1872 VNC_DEBUG("Start VNC auth\n");
1873 start_auth_vnc(vs);
1874 break;
1876 #ifdef CONFIG_VNC_TLS
1877 case VNC_AUTH_VENCRYPT:
1878 VNC_DEBUG("Accept VeNCrypt auth\n");;
1879 start_auth_vencrypt(vs);
1880 break;
1881 #endif /* CONFIG_VNC_TLS */
1883 #ifdef CONFIG_VNC_SASL
1884 case VNC_AUTH_SASL:
1885 VNC_DEBUG("Accept SASL auth\n");
1886 start_auth_sasl(vs);
1887 break;
1888 #endif /* CONFIG_VNC_SASL */
1890 default: /* Should not be possible, but just in case */
1891 VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth);
1892 vnc_write_u8(vs, 1);
1893 if (vs->minor >= 8) {
1894 static const char err[] = "Authentication failed";
1895 vnc_write_u32(vs, sizeof(err));
1896 vnc_write(vs, err, sizeof(err));
1898 vnc_client_error(vs);
1901 return 0;
1904 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1906 char local[13];
1908 memcpy(local, version, 12);
1909 local[12] = 0;
1911 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1912 VNC_DEBUG("Malformed protocol version %s\n", local);
1913 vnc_client_error(vs);
1914 return 0;
1916 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1917 if (vs->major != 3 ||
1918 (vs->minor != 3 &&
1919 vs->minor != 4 &&
1920 vs->minor != 5 &&
1921 vs->minor != 7 &&
1922 vs->minor != 8)) {
1923 VNC_DEBUG("Unsupported client version\n");
1924 vnc_write_u32(vs, VNC_AUTH_INVALID);
1925 vnc_flush(vs);
1926 vnc_client_error(vs);
1927 return 0;
1929 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1930 * as equivalent to v3.3 by servers
1932 if (vs->minor == 4 || vs->minor == 5)
1933 vs->minor = 3;
1935 if (vs->minor == 3) {
1936 if (vs->vd->auth == VNC_AUTH_NONE) {
1937 VNC_DEBUG("Tell client auth none\n");
1938 vnc_write_u32(vs, vs->vd->auth);
1939 vnc_flush(vs);
1940 start_client_init(vs);
1941 } else if (vs->vd->auth == VNC_AUTH_VNC) {
1942 VNC_DEBUG("Tell client VNC auth\n");
1943 vnc_write_u32(vs, vs->vd->auth);
1944 vnc_flush(vs);
1945 start_auth_vnc(vs);
1946 } else {
1947 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
1948 vnc_write_u32(vs, VNC_AUTH_INVALID);
1949 vnc_flush(vs);
1950 vnc_client_error(vs);
1952 } else {
1953 VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
1954 vnc_write_u8(vs, 1); /* num auth */
1955 vnc_write_u8(vs, vs->vd->auth);
1956 vnc_read_when(vs, protocol_client_auth, 1);
1957 vnc_flush(vs);
1960 return 0;
1963 static void vnc_connect(VncDisplay *vd, int csock)
1965 VncState *vs = qemu_mallocz(sizeof(VncState));
1966 vs->csock = csock;
1968 VNC_DEBUG("New client on socket %d\n", csock);
1969 dcl->idle = 0;
1970 socket_set_nonblock(vs->csock);
1971 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1973 vs->vd = vd;
1974 vs->ds = vd->ds;
1975 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
1976 vs->last_x = -1;
1977 vs->last_y = -1;
1979 vs->as.freq = 44100;
1980 vs->as.nchannels = 2;
1981 vs->as.fmt = AUD_FMT_S16;
1982 vs->as.endianness = 0;
1984 vnc_resize(vs);
1985 vnc_write(vs, "RFB 003.008\n", 12);
1986 vnc_flush(vs);
1987 vnc_read_when(vs, protocol_version, 12);
1988 memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
1989 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1990 vnc_update_client(vs);
1991 reset_keys(vs);
1993 vs->next = vd->clients;
1994 vd->clients = vs;
1997 static void vnc_listen_read(void *opaque)
1999 VncDisplay *vs = opaque;
2000 struct sockaddr_in addr;
2001 socklen_t addrlen = sizeof(addr);
2003 /* Catch-up */
2004 vga_hw_update();
2006 int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
2007 if (csock != -1) {
2008 vnc_connect(vs, csock);
2012 void vnc_display_init(DisplayState *ds)
2014 VncDisplay *vs;
2016 vs = qemu_mallocz(sizeof(VncState));
2017 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
2019 ds->opaque = vs;
2020 dcl->idle = 1;
2021 vnc_display = vs;
2023 vs->lsock = -1;
2025 vs->ds = ds;
2027 if (keyboard_layout)
2028 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
2029 else
2030 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
2032 if (!vs->kbd_layout)
2033 exit(1);
2035 dcl->dpy_copy = vnc_dpy_copy;
2036 dcl->dpy_update = vnc_dpy_update;
2037 dcl->dpy_resize = vnc_dpy_resize;
2038 dcl->dpy_setdata = vnc_dpy_setdata;
2039 register_displaychangelistener(ds, dcl);
2043 void vnc_display_close(DisplayState *ds)
2045 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2047 if (!vs)
2048 return;
2049 if (vs->display) {
2050 qemu_free(vs->display);
2051 vs->display = NULL;
2053 if (vs->lsock != -1) {
2054 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2055 close(vs->lsock);
2056 vs->lsock = -1;
2058 vs->auth = VNC_AUTH_INVALID;
2059 #ifdef CONFIG_VNC_TLS
2060 vs->subauth = VNC_AUTH_INVALID;
2061 vs->tls.x509verify = 0;
2062 #endif
2065 int vnc_display_password(DisplayState *ds, const char *password)
2067 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2069 if (vs->password) {
2070 qemu_free(vs->password);
2071 vs->password = NULL;
2073 if (password && password[0]) {
2074 if (!(vs->password = qemu_strdup(password)))
2075 return -1;
2078 return 0;
2081 int vnc_display_open(DisplayState *ds, const char *display)
2083 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2084 const char *options;
2085 int password = 0;
2086 int reverse = 0;
2087 int to_port = 0;
2088 #ifdef CONFIG_VNC_TLS
2089 int tls = 0, x509 = 0;
2090 #endif
2091 #ifdef CONFIG_VNC_SASL
2092 int sasl = 0;
2093 int saslErr;
2094 #endif
2095 int acl = 0;
2097 if (!vnc_display)
2098 return -1;
2099 vnc_display_close(ds);
2100 if (strcmp(display, "none") == 0)
2101 return 0;
2103 if (!(vs->display = strdup(display)))
2104 return -1;
2106 options = display;
2107 while ((options = strchr(options, ','))) {
2108 options++;
2109 if (strncmp(options, "password", 8) == 0) {
2110 password = 1; /* Require password auth */
2111 } else if (strncmp(options, "reverse", 7) == 0) {
2112 reverse = 1;
2113 } else if (strncmp(options, "to=", 3) == 0) {
2114 to_port = atoi(options+3) + 5900;
2115 #ifdef CONFIG_VNC_SASL
2116 } else if (strncmp(options, "sasl", 4) == 0) {
2117 sasl = 1; /* Require SASL auth */
2118 #endif
2119 #ifdef CONFIG_VNC_TLS
2120 } else if (strncmp(options, "tls", 3) == 0) {
2121 tls = 1; /* Require TLS */
2122 } else if (strncmp(options, "x509", 4) == 0) {
2123 char *start, *end;
2124 x509 = 1; /* Require x509 certificates */
2125 if (strncmp(options, "x509verify", 10) == 0)
2126 vs->tls.x509verify = 1; /* ...and verify client certs */
2128 /* Now check for 'x509=/some/path' postfix
2129 * and use that to setup x509 certificate/key paths */
2130 start = strchr(options, '=');
2131 end = strchr(options, ',');
2132 if (start && (!end || (start < end))) {
2133 int len = end ? end-(start+1) : strlen(start+1);
2134 char *path = qemu_strndup(start + 1, len);
2136 VNC_DEBUG("Trying certificate path '%s'\n", path);
2137 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2138 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2139 qemu_free(path);
2140 qemu_free(vs->display);
2141 vs->display = NULL;
2142 return -1;
2144 qemu_free(path);
2145 } else {
2146 fprintf(stderr, "No certificate path provided\n");
2147 qemu_free(vs->display);
2148 vs->display = NULL;
2149 return -1;
2151 #endif
2152 } else if (strncmp(options, "acl", 3) == 0) {
2153 acl = 1;
2157 #ifdef CONFIG_VNC_TLS
2158 if (acl && x509 && vs->tls.x509verify) {
2159 if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
2160 fprintf(stderr, "Failed to create x509 dname ACL\n");
2161 exit(1);
2164 #endif
2165 #ifdef CONFIG_VNC_SASL
2166 if (acl && sasl) {
2167 if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
2168 fprintf(stderr, "Failed to create username ACL\n");
2169 exit(1);
2172 #endif
2175 * Combinations we support here:
2177 * - no-auth (clear text, no auth)
2178 * - password (clear text, weak auth)
2179 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
2180 * - tls (encrypt, weak anonymous creds, no auth)
2181 * - tls + password (encrypt, weak anonymous creds, weak auth)
2182 * - tls + sasl (encrypt, weak anonymous creds, good auth)
2183 * - tls + x509 (encrypt, good x509 creds, no auth)
2184 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
2185 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
2187 * NB1. TLS is a stackable auth scheme.
2188 * NB2. the x509 schemes have option to validate a client cert dname
2190 if (password) {
2191 #ifdef CONFIG_VNC_TLS
2192 if (tls) {
2193 vs->auth = VNC_AUTH_VENCRYPT;
2194 if (x509) {
2195 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2196 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2197 } else {
2198 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2199 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2201 } else {
2202 #endif /* CONFIG_VNC_TLS */
2203 VNC_DEBUG("Initializing VNC server with password auth\n");
2204 vs->auth = VNC_AUTH_VNC;
2205 #ifdef CONFIG_VNC_TLS
2206 vs->subauth = VNC_AUTH_INVALID;
2208 #endif /* CONFIG_VNC_TLS */
2209 #ifdef CONFIG_VNC_SASL
2210 } else if (sasl) {
2211 #ifdef CONFIG_VNC_TLS
2212 if (tls) {
2213 vs->auth = VNC_AUTH_VENCRYPT;
2214 if (x509) {
2215 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
2216 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
2217 } else {
2218 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
2219 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
2221 } else {
2222 #endif /* CONFIG_VNC_TLS */
2223 VNC_DEBUG("Initializing VNC server with SASL auth\n");
2224 vs->auth = VNC_AUTH_SASL;
2225 #ifdef CONFIG_VNC_TLS
2226 vs->subauth = VNC_AUTH_INVALID;
2228 #endif /* CONFIG_VNC_TLS */
2229 #endif /* CONFIG_VNC_SASL */
2230 } else {
2231 #ifdef CONFIG_VNC_TLS
2232 if (tls) {
2233 vs->auth = VNC_AUTH_VENCRYPT;
2234 if (x509) {
2235 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2236 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2237 } else {
2238 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2239 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2241 } else {
2242 #endif
2243 VNC_DEBUG("Initializing VNC server with no auth\n");
2244 vs->auth = VNC_AUTH_NONE;
2245 #ifdef CONFIG_VNC_TLS
2246 vs->subauth = VNC_AUTH_INVALID;
2248 #endif
2251 #ifdef CONFIG_VNC_SASL
2252 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2253 fprintf(stderr, "Failed to initialize SASL auth %s",
2254 sasl_errstring(saslErr, NULL, NULL));
2255 free(vs->display);
2256 vs->display = NULL;
2257 return -1;
2259 #endif
2261 if (reverse) {
2262 /* connect to viewer */
2263 if (strncmp(display, "unix:", 5) == 0)
2264 vs->lsock = unix_connect(display+5);
2265 else
2266 vs->lsock = inet_connect(display, SOCK_STREAM);
2267 if (-1 == vs->lsock) {
2268 free(vs->display);
2269 vs->display = NULL;
2270 return -1;
2271 } else {
2272 int csock = vs->lsock;
2273 vs->lsock = -1;
2274 vnc_connect(vs, csock);
2276 return 0;
2278 } else {
2279 /* listen for connects */
2280 char *dpy;
2281 dpy = qemu_malloc(256);
2282 if (strncmp(display, "unix:", 5) == 0) {
2283 pstrcpy(dpy, 256, "unix:");
2284 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
2285 } else {
2286 vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
2288 if (-1 == vs->lsock) {
2289 free(dpy);
2290 return -1;
2291 } else {
2292 free(vs->display);
2293 vs->display = dpy;
2296 return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);