[S3C] Make s3c aware of 2440s
[sniper_test.git] / vnc.c
bloba67d23f8b1bda9c0ea29ee689404bc34ef29f168
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(Monitor *mon, VncState *client)
151 char *clientAddr =
152 vnc_socket_remote_addr(" address: %s:%s\n",
153 client->csock);
154 if (!clientAddr)
155 return;
157 monitor_printf(mon, "Client:\n");
158 monitor_printf(mon, "%s", clientAddr);
159 free(clientAddr);
161 #ifdef CONFIG_VNC_TLS
162 if (client->tls.session &&
163 client->tls.dname)
164 monitor_printf(mon, " x509 dname: %s\n", client->tls.dname);
165 else
166 monitor_printf(mon, " x509 dname: none\n");
167 #endif
168 #ifdef CONFIG_VNC_SASL
169 if (client->sasl.conn &&
170 client->sasl.username)
171 monitor_printf(mon, " username: %s\n", client->sasl.username);
172 else
173 monitor_printf(mon, " username: none\n");
174 #endif
177 void do_info_vnc(Monitor *mon)
179 if (vnc_display == NULL || vnc_display->display == NULL) {
180 monitor_printf(mon, "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 monitor_printf(mon, "Server:\n");
189 monitor_printf(mon, "%s", serverAddr);
190 free(serverAddr);
191 monitor_printf(mon, " 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(mon, client);
197 client = client->next;
199 } else {
200 monitor_printf(mon, "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 Monitor *mon = cur_mon;
824 struct audio_capture_ops ops;
826 if (vs->audio_cap) {
827 monitor_printf(mon, "audio already running\n");
828 return;
831 ops.notify = audio_capture_notify;
832 ops.destroy = audio_capture_destroy;
833 ops.capture = audio_capture;
835 vs->audio_cap = AUD_add_capture(NULL, &vs->as, &ops, vs);
836 if (!vs->audio_cap) {
837 monitor_printf(mon, "Failed to add audio capture\n");
841 static void audio_del(VncState *vs)
843 if (vs->audio_cap) {
844 AUD_del_capture(vs->audio_cap, vs);
845 vs->audio_cap = NULL;
850 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
852 if (ret == 0 || ret == -1) {
853 if (ret == -1) {
854 switch (last_errno) {
855 case EINTR:
856 case EAGAIN:
857 #ifdef _WIN32
858 case WSAEWOULDBLOCK:
859 #endif
860 return 0;
861 default:
862 break;
866 VNC_DEBUG("Closing down client sock %d %d\n", ret, ret < 0 ? last_errno : 0);
867 qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
868 closesocket(vs->csock);
869 qemu_del_timer(vs->timer);
870 qemu_free_timer(vs->timer);
871 if (vs->input.buffer) qemu_free(vs->input.buffer);
872 if (vs->output.buffer) qemu_free(vs->output.buffer);
873 #ifdef CONFIG_VNC_TLS
874 vnc_tls_client_cleanup(vs);
875 #endif /* CONFIG_VNC_TLS */
876 #ifdef CONFIG_VNC_SASL
877 vnc_sasl_client_cleanup(vs);
878 #endif /* CONFIG_VNC_SASL */
879 audio_del(vs);
881 VncState *p, *parent = NULL;
882 for (p = vs->vd->clients; p != NULL; p = p->next) {
883 if (p == vs) {
884 if (parent)
885 parent->next = p->next;
886 else
887 vs->vd->clients = p->next;
888 break;
890 parent = p;
892 if (!vs->vd->clients)
893 dcl->idle = 1;
895 qemu_free(vs->old_data);
896 qemu_free(vs);
898 return 0;
900 return ret;
904 void vnc_client_error(VncState *vs)
906 vnc_client_io_error(vs, -1, EINVAL);
911 * Called to write a chunk of data to the client socket. The data may
912 * be the raw data, or may have already been encoded by SASL.
913 * The data will be written either straight onto the socket, or
914 * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
916 * NB, it is theoretically possible to have 2 layers of encryption,
917 * both SASL, and this TLS layer. It is highly unlikely in practice
918 * though, since SASL encryption will typically be a no-op if TLS
919 * is active
921 * Returns the number of bytes written, which may be less than
922 * the requested 'datalen' if the socket would block. Returns
923 * -1 on error, and disconnects the client socket.
925 long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
927 long ret;
928 #ifdef CONFIG_VNC_TLS
929 if (vs->tls.session) {
930 ret = gnutls_write(vs->tls.session, data, datalen);
931 if (ret < 0) {
932 if (ret == GNUTLS_E_AGAIN)
933 errno = EAGAIN;
934 else
935 errno = EIO;
936 ret = -1;
938 } else
939 #endif /* CONFIG_VNC_TLS */
940 ret = send(vs->csock, data, datalen, 0);
941 VNC_DEBUG("Wrote wire %p %d -> %ld\n", data, datalen, ret);
942 return vnc_client_io_error(vs, ret, socket_error());
947 * Called to write buffered data to the client socket, when not
948 * using any SASL SSF encryption layers. Will write as much data
949 * as possible without blocking. If all buffered data is written,
950 * will switch the FD poll() handler back to read monitoring.
952 * Returns the number of bytes written, which may be less than
953 * the buffered output data if the socket would block. Returns
954 * -1 on error, and disconnects the client socket.
956 static long vnc_client_write_plain(VncState *vs)
958 long ret;
960 #ifdef CONFIG_VNC_SASL
961 VNC_DEBUG("Write Plain: Pending output %p size %d offset %d. Wait SSF %d\n",
962 vs->output.buffer, vs->output.capacity, vs->output.offset,
963 vs->sasl.waitWriteSSF);
965 if (vs->sasl.conn &&
966 vs->sasl.runSSF &&
967 vs->sasl.waitWriteSSF) {
968 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
969 if (ret)
970 vs->sasl.waitWriteSSF -= ret;
971 } else
972 #endif /* CONFIG_VNC_SASL */
973 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
974 if (!ret)
975 return 0;
977 memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));
978 vs->output.offset -= ret;
980 if (vs->output.offset == 0) {
981 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
984 return ret;
989 * First function called whenever there is data to be written to
990 * the client socket. Will delegate actual work according to whether
991 * SASL SSF layers are enabled (thus requiring encryption calls)
993 void vnc_client_write(void *opaque)
995 long ret;
996 VncState *vs = opaque;
998 #ifdef CONFIG_VNC_SASL
999 if (vs->sasl.conn &&
1000 vs->sasl.runSSF &&
1001 !vs->sasl.waitWriteSSF)
1002 ret = vnc_client_write_sasl(vs);
1003 else
1004 #endif /* CONFIG_VNC_SASL */
1005 ret = vnc_client_write_plain(vs);
1008 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1010 vs->read_handler = func;
1011 vs->read_handler_expect = expecting;
1016 * Called to read a chunk of data from the client socket. The data may
1017 * be the raw data, or may need to be further decoded by SASL.
1018 * The data will be read either straight from to the socket, or
1019 * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
1021 * NB, it is theoretically possible to have 2 layers of encryption,
1022 * both SASL, and this TLS layer. It is highly unlikely in practice
1023 * though, since SASL encryption will typically be a no-op if TLS
1024 * is active
1026 * Returns the number of bytes read, which may be less than
1027 * the requested 'datalen' if the socket would block. Returns
1028 * -1 on error, and disconnects the client socket.
1030 long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1032 long ret;
1033 #ifdef CONFIG_VNC_TLS
1034 if (vs->tls.session) {
1035 ret = gnutls_read(vs->tls.session, data, datalen);
1036 if (ret < 0) {
1037 if (ret == GNUTLS_E_AGAIN)
1038 errno = EAGAIN;
1039 else
1040 errno = EIO;
1041 ret = -1;
1043 } else
1044 #endif /* CONFIG_VNC_TLS */
1045 ret = recv(vs->csock, data, datalen, 0);
1046 VNC_DEBUG("Read wire %p %d -> %ld\n", data, datalen, ret);
1047 return vnc_client_io_error(vs, ret, socket_error());
1052 * Called to read data from the client socket to the input buffer,
1053 * when not using any SASL SSF encryption layers. Will read as much
1054 * data as possible without blocking.
1056 * Returns the number of bytes read. Returns -1 on error, and
1057 * disconnects the client socket.
1059 static long vnc_client_read_plain(VncState *vs)
1061 int ret;
1062 VNC_DEBUG("Read plain %p size %d offset %d\n",
1063 vs->input.buffer, vs->input.capacity, vs->input.offset);
1064 buffer_reserve(&vs->input, 4096);
1065 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1066 if (!ret)
1067 return 0;
1068 vs->input.offset += ret;
1069 return ret;
1074 * First function called whenever there is more data to be read from
1075 * the client socket. Will delegate actual work according to whether
1076 * SASL SSF layers are enabled (thus requiring decryption calls)
1078 void vnc_client_read(void *opaque)
1080 VncState *vs = opaque;
1081 long ret;
1083 #ifdef CONFIG_VNC_SASL
1084 if (vs->sasl.conn && vs->sasl.runSSF)
1085 ret = vnc_client_read_sasl(vs);
1086 else
1087 #endif /* CONFIG_VNC_SASL */
1088 ret = vnc_client_read_plain(vs);
1089 if (!ret)
1090 return;
1092 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1093 size_t len = vs->read_handler_expect;
1094 int ret;
1096 ret = vs->read_handler(vs, vs->input.buffer, len);
1097 if (vs->csock == -1)
1098 return;
1100 if (!ret) {
1101 memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));
1102 vs->input.offset -= len;
1103 } else {
1104 vs->read_handler_expect = ret;
1109 void vnc_write(VncState *vs, const void *data, size_t len)
1111 buffer_reserve(&vs->output, len);
1113 if (buffer_empty(&vs->output)) {
1114 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);
1117 buffer_append(&vs->output, data, len);
1120 void vnc_write_s32(VncState *vs, int32_t value)
1122 vnc_write_u32(vs, *(uint32_t *)&value);
1125 void vnc_write_u32(VncState *vs, uint32_t value)
1127 uint8_t buf[4];
1129 buf[0] = (value >> 24) & 0xFF;
1130 buf[1] = (value >> 16) & 0xFF;
1131 buf[2] = (value >> 8) & 0xFF;
1132 buf[3] = value & 0xFF;
1134 vnc_write(vs, buf, 4);
1137 void vnc_write_u16(VncState *vs, uint16_t value)
1139 uint8_t buf[2];
1141 buf[0] = (value >> 8) & 0xFF;
1142 buf[1] = value & 0xFF;
1144 vnc_write(vs, buf, 2);
1147 void vnc_write_u8(VncState *vs, uint8_t value)
1149 vnc_write(vs, (char *)&value, 1);
1152 void vnc_flush(VncState *vs)
1154 if (vs->output.offset)
1155 vnc_client_write(vs);
1158 uint8_t read_u8(uint8_t *data, size_t offset)
1160 return data[offset];
1163 uint16_t read_u16(uint8_t *data, size_t offset)
1165 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1168 int32_t read_s32(uint8_t *data, size_t offset)
1170 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1171 (data[offset + 2] << 8) | data[offset + 3]);
1174 uint32_t read_u32(uint8_t *data, size_t offset)
1176 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1177 (data[offset + 2] << 8) | data[offset + 3]);
1180 static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1184 static void check_pointer_type_change(VncState *vs, int absolute)
1186 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1187 vnc_write_u8(vs, 0);
1188 vnc_write_u8(vs, 0);
1189 vnc_write_u16(vs, 1);
1190 vnc_framebuffer_update(vs, absolute, 0,
1191 ds_get_width(vs->ds), ds_get_height(vs->ds),
1192 VNC_ENCODING_POINTER_TYPE_CHANGE);
1193 vnc_flush(vs);
1195 vs->absolute = absolute;
1198 static void pointer_event(VncState *vs, int button_mask, int x, int y)
1200 int buttons = 0;
1201 int dz = 0;
1203 if (button_mask & 0x01)
1204 buttons |= MOUSE_EVENT_LBUTTON;
1205 if (button_mask & 0x02)
1206 buttons |= MOUSE_EVENT_MBUTTON;
1207 if (button_mask & 0x04)
1208 buttons |= MOUSE_EVENT_RBUTTON;
1209 if (button_mask & 0x08)
1210 dz = -1;
1211 if (button_mask & 0x10)
1212 dz = 1;
1214 if (vs->absolute) {
1215 kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
1216 y * 0x7FFF / (ds_get_height(vs->ds) - 1),
1217 dz, buttons);
1218 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1219 x -= 0x7FFF;
1220 y -= 0x7FFF;
1222 kbd_mouse_event(x, y, dz, buttons);
1223 } else {
1224 if (vs->last_x != -1)
1225 kbd_mouse_event(x - vs->last_x,
1226 y - vs->last_y,
1227 dz, buttons);
1228 vs->last_x = x;
1229 vs->last_y = y;
1232 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1235 static void reset_keys(VncState *vs)
1237 int i;
1238 for(i = 0; i < 256; i++) {
1239 if (vs->modifiers_state[i]) {
1240 if (i & 0x80)
1241 kbd_put_keycode(0xe0);
1242 kbd_put_keycode(i | 0x80);
1243 vs->modifiers_state[i] = 0;
1248 static void press_key(VncState *vs, int keysym)
1250 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) & 0x7f);
1251 kbd_put_keycode(keysym2scancode(vs->vd->kbd_layout, keysym) | 0x80);
1254 static void do_key_event(VncState *vs, int down, int keycode, int sym)
1256 /* QEMU console switch */
1257 switch(keycode) {
1258 case 0x2a: /* Left Shift */
1259 case 0x36: /* Right Shift */
1260 case 0x1d: /* Left CTRL */
1261 case 0x9d: /* Right CTRL */
1262 case 0x38: /* Left ALT */
1263 case 0xb8: /* Right ALT */
1264 if (down)
1265 vs->modifiers_state[keycode] = 1;
1266 else
1267 vs->modifiers_state[keycode] = 0;
1268 break;
1269 case 0x02 ... 0x0a: /* '1' to '9' keys */
1270 if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
1271 /* Reset the modifiers sent to the current console */
1272 reset_keys(vs);
1273 console_select(keycode - 0x02);
1274 return;
1276 break;
1277 case 0x3a: /* CapsLock */
1278 case 0x45: /* NumLock */
1279 if (!down)
1280 vs->modifiers_state[keycode] ^= 1;
1281 break;
1284 if (keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1285 /* If the numlock state needs to change then simulate an additional
1286 keypress before sending this one. This will happen if the user
1287 toggles numlock away from the VNC window.
1289 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1290 if (!vs->modifiers_state[0x45]) {
1291 vs->modifiers_state[0x45] = 1;
1292 press_key(vs, 0xff7f);
1294 } else {
1295 if (vs->modifiers_state[0x45]) {
1296 vs->modifiers_state[0x45] = 0;
1297 press_key(vs, 0xff7f);
1302 if (is_graphic_console()) {
1303 if (keycode & 0x80)
1304 kbd_put_keycode(0xe0);
1305 if (down)
1306 kbd_put_keycode(keycode & 0x7f);
1307 else
1308 kbd_put_keycode(keycode | 0x80);
1309 } else {
1310 /* QEMU console emulation */
1311 if (down) {
1312 switch (keycode) {
1313 case 0x2a: /* Left Shift */
1314 case 0x36: /* Right Shift */
1315 case 0x1d: /* Left CTRL */
1316 case 0x9d: /* Right CTRL */
1317 case 0x38: /* Left ALT */
1318 case 0xb8: /* Right ALT */
1319 break;
1320 case 0xc8:
1321 kbd_put_keysym(QEMU_KEY_UP);
1322 break;
1323 case 0xd0:
1324 kbd_put_keysym(QEMU_KEY_DOWN);
1325 break;
1326 case 0xcb:
1327 kbd_put_keysym(QEMU_KEY_LEFT);
1328 break;
1329 case 0xcd:
1330 kbd_put_keysym(QEMU_KEY_RIGHT);
1331 break;
1332 case 0xd3:
1333 kbd_put_keysym(QEMU_KEY_DELETE);
1334 break;
1335 case 0xc7:
1336 kbd_put_keysym(QEMU_KEY_HOME);
1337 break;
1338 case 0xcf:
1339 kbd_put_keysym(QEMU_KEY_END);
1340 break;
1341 case 0xc9:
1342 kbd_put_keysym(QEMU_KEY_PAGEUP);
1343 break;
1344 case 0xd1:
1345 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1346 break;
1347 default:
1348 kbd_put_keysym(sym);
1349 break;
1355 static void key_event(VncState *vs, int down, uint32_t sym)
1357 int keycode;
1359 if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
1360 sym = sym - 'A' + 'a';
1362 keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
1363 do_key_event(vs, down, keycode, sym);
1366 static void ext_key_event(VncState *vs, int down,
1367 uint32_t sym, uint16_t keycode)
1369 /* if the user specifies a keyboard layout, always use it */
1370 if (keyboard_layout)
1371 key_event(vs, down, sym);
1372 else
1373 do_key_event(vs, down, keycode, sym);
1376 static void framebuffer_update_request(VncState *vs, int incremental,
1377 int x_position, int y_position,
1378 int w, int h)
1380 if (x_position > ds_get_width(vs->ds))
1381 x_position = ds_get_width(vs->ds);
1382 if (y_position > ds_get_height(vs->ds))
1383 y_position = ds_get_height(vs->ds);
1384 if (x_position + w >= ds_get_width(vs->ds))
1385 w = ds_get_width(vs->ds) - x_position;
1386 if (y_position + h >= ds_get_height(vs->ds))
1387 h = ds_get_height(vs->ds) - y_position;
1389 int i;
1390 vs->need_update = 1;
1391 if (!incremental) {
1392 char *old_row = vs->old_data + y_position * ds_get_linesize(vs->ds);
1394 for (i = 0; i < h; i++) {
1395 vnc_set_bits(vs->dirty_row[y_position + i],
1396 (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1397 memset(old_row, 42, ds_get_width(vs->ds) * ds_get_bytes_per_pixel(vs->ds));
1398 old_row += ds_get_linesize(vs->ds);
1403 static void send_ext_key_event_ack(VncState *vs)
1405 vnc_write_u8(vs, 0);
1406 vnc_write_u8(vs, 0);
1407 vnc_write_u16(vs, 1);
1408 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1409 VNC_ENCODING_EXT_KEY_EVENT);
1410 vnc_flush(vs);
1413 static void send_ext_audio_ack(VncState *vs)
1415 vnc_write_u8(vs, 0);
1416 vnc_write_u8(vs, 0);
1417 vnc_write_u16(vs, 1);
1418 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
1419 VNC_ENCODING_AUDIO);
1420 vnc_flush(vs);
1423 static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
1425 int i;
1426 unsigned int enc = 0;
1428 vnc_zlib_init(vs);
1429 vs->features = 0;
1430 vs->vnc_encoding = 0;
1431 vs->tight_compression = 9;
1432 vs->tight_quality = 9;
1433 vs->absolute = -1;
1435 for (i = n_encodings - 1; i >= 0; i--) {
1436 enc = encodings[i];
1437 switch (enc) {
1438 case VNC_ENCODING_RAW:
1439 vs->vnc_encoding = enc;
1440 break;
1441 case VNC_ENCODING_COPYRECT:
1442 vs->features |= VNC_FEATURE_COPYRECT_MASK;
1443 break;
1444 case VNC_ENCODING_HEXTILE:
1445 vs->features |= VNC_FEATURE_HEXTILE_MASK;
1446 vs->vnc_encoding = enc;
1447 break;
1448 case VNC_ENCODING_ZLIB:
1449 vs->features |= VNC_FEATURE_ZLIB_MASK;
1450 vs->vnc_encoding = enc;
1451 break;
1452 case VNC_ENCODING_DESKTOPRESIZE:
1453 vs->features |= VNC_FEATURE_RESIZE_MASK;
1454 break;
1455 case VNC_ENCODING_POINTER_TYPE_CHANGE:
1456 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
1457 break;
1458 case VNC_ENCODING_EXT_KEY_EVENT:
1459 send_ext_key_event_ack(vs);
1460 break;
1461 case VNC_ENCODING_AUDIO:
1462 send_ext_audio_ack(vs);
1463 break;
1464 case VNC_ENCODING_WMVi:
1465 vs->features |= VNC_FEATURE_WMVI_MASK;
1466 break;
1467 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
1468 vs->tight_compression = (enc & 0x0F);
1469 break;
1470 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
1471 vs->tight_quality = (enc & 0x0F);
1472 break;
1473 default:
1474 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
1475 break;
1479 check_pointer_type_change(vs, kbd_mouse_is_absolute());
1482 static void set_pixel_conversion(VncState *vs)
1484 if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
1485 (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) &&
1486 !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
1487 vs->write_pixels = vnc_write_pixels_copy;
1488 switch (vs->ds->surface->pf.bits_per_pixel) {
1489 case 8:
1490 vs->send_hextile_tile = send_hextile_tile_8;
1491 break;
1492 case 16:
1493 vs->send_hextile_tile = send_hextile_tile_16;
1494 break;
1495 case 32:
1496 vs->send_hextile_tile = send_hextile_tile_32;
1497 break;
1499 } else {
1500 vs->write_pixels = vnc_write_pixels_generic;
1501 switch (vs->ds->surface->pf.bits_per_pixel) {
1502 case 8:
1503 vs->send_hextile_tile = send_hextile_tile_generic_8;
1504 break;
1505 case 16:
1506 vs->send_hextile_tile = send_hextile_tile_generic_16;
1507 break;
1508 case 32:
1509 vs->send_hextile_tile = send_hextile_tile_generic_32;
1510 break;
1515 static void set_pixel_format(VncState *vs,
1516 int bits_per_pixel, int depth,
1517 int big_endian_flag, int true_color_flag,
1518 int red_max, int green_max, int blue_max,
1519 int red_shift, int green_shift, int blue_shift)
1521 if (!true_color_flag) {
1522 vnc_client_error(vs);
1523 return;
1526 vs->clientds = vs->serverds;
1527 vs->clientds.pf.rmax = red_max;
1528 count_bits(vs->clientds.pf.rbits, red_max);
1529 vs->clientds.pf.rshift = red_shift;
1530 vs->clientds.pf.rmask = red_max << red_shift;
1531 vs->clientds.pf.gmax = green_max;
1532 count_bits(vs->clientds.pf.gbits, green_max);
1533 vs->clientds.pf.gshift = green_shift;
1534 vs->clientds.pf.gmask = green_max << green_shift;
1535 vs->clientds.pf.bmax = blue_max;
1536 count_bits(vs->clientds.pf.bbits, blue_max);
1537 vs->clientds.pf.bshift = blue_shift;
1538 vs->clientds.pf.bmask = blue_max << blue_shift;
1539 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
1540 vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
1541 vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
1542 vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
1544 set_pixel_conversion(vs);
1546 vga_hw_invalidate();
1547 vga_hw_update();
1550 static void pixel_format_message (VncState *vs) {
1551 char pad[3] = { 0, 0, 0 };
1553 vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
1554 vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
1556 #ifdef WORDS_BIGENDIAN
1557 vnc_write_u8(vs, 1); /* big-endian-flag */
1558 #else
1559 vnc_write_u8(vs, 0); /* big-endian-flag */
1560 #endif
1561 vnc_write_u8(vs, 1); /* true-color-flag */
1562 vnc_write_u16(vs, vs->ds->surface->pf.rmax); /* red-max */
1563 vnc_write_u16(vs, vs->ds->surface->pf.gmax); /* green-max */
1564 vnc_write_u16(vs, vs->ds->surface->pf.bmax); /* blue-max */
1565 vnc_write_u8(vs, vs->ds->surface->pf.rshift); /* red-shift */
1566 vnc_write_u8(vs, vs->ds->surface->pf.gshift); /* green-shift */
1567 vnc_write_u8(vs, vs->ds->surface->pf.bshift); /* blue-shift */
1568 if (vs->ds->surface->pf.bits_per_pixel == 32)
1569 vs->send_hextile_tile = send_hextile_tile_32;
1570 else if (vs->ds->surface->pf.bits_per_pixel == 16)
1571 vs->send_hextile_tile = send_hextile_tile_16;
1572 else if (vs->ds->surface->pf.bits_per_pixel == 8)
1573 vs->send_hextile_tile = send_hextile_tile_8;
1574 vs->clientds = *(vs->ds->surface);
1575 vs->clientds.flags |= ~QEMU_ALLOCATED_FLAG;
1576 vs->write_pixels = vnc_write_pixels_copy;
1578 vnc_write(vs, pad, 3); /* padding */
1581 static void vnc_dpy_setdata(DisplayState *ds)
1583 /* We don't have to do anything */
1586 static void vnc_colordepth(VncState *vs)
1588 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
1589 /* Sending a WMVi message to notify the client*/
1590 vnc_write_u8(vs, 0); /* msg id */
1591 vnc_write_u8(vs, 0);
1592 vnc_write_u16(vs, 1); /* number of rects */
1593 vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
1594 ds_get_height(vs->ds), VNC_ENCODING_WMVi);
1595 pixel_format_message(vs);
1596 vnc_flush(vs);
1597 } else {
1598 set_pixel_conversion(vs);
1602 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
1604 int i;
1605 uint16_t limit;
1607 switch (data[0]) {
1608 case 0:
1609 if (len == 1)
1610 return 20;
1612 set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
1613 read_u8(data, 6), read_u8(data, 7),
1614 read_u16(data, 8), read_u16(data, 10),
1615 read_u16(data, 12), read_u8(data, 14),
1616 read_u8(data, 15), read_u8(data, 16));
1617 break;
1618 case 2:
1619 if (len == 1)
1620 return 4;
1622 if (len == 4) {
1623 limit = read_u16(data, 2);
1624 if (limit > 0)
1625 return 4 + (limit * 4);
1626 } else
1627 limit = read_u16(data, 2);
1629 for (i = 0; i < limit; i++) {
1630 int32_t val = read_s32(data, 4 + (i * 4));
1631 memcpy(data + 4 + (i * 4), &val, sizeof(val));
1634 set_encodings(vs, (int32_t *)(data + 4), limit);
1635 break;
1636 case 3:
1637 if (len == 1)
1638 return 10;
1640 framebuffer_update_request(vs,
1641 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
1642 read_u16(data, 6), read_u16(data, 8));
1643 break;
1644 case 4:
1645 if (len == 1)
1646 return 8;
1648 key_event(vs, read_u8(data, 1), read_u32(data, 4));
1649 break;
1650 case 5:
1651 if (len == 1)
1652 return 6;
1654 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
1655 break;
1656 case 6:
1657 if (len == 1)
1658 return 8;
1660 if (len == 8) {
1661 uint32_t dlen = read_u32(data, 4);
1662 if (dlen > 0)
1663 return 8 + dlen;
1666 client_cut_text(vs, read_u32(data, 4), data + 8);
1667 break;
1668 case 255:
1669 if (len == 1)
1670 return 2;
1672 switch (read_u8(data, 1)) {
1673 case 0:
1674 if (len == 2)
1675 return 12;
1677 ext_key_event(vs, read_u16(data, 2),
1678 read_u32(data, 4), read_u32(data, 8));
1679 break;
1680 case 1:
1681 if (len == 2)
1682 return 4;
1684 switch (read_u16 (data, 2)) {
1685 case 0:
1686 audio_add(vs);
1687 break;
1688 case 1:
1689 audio_del(vs);
1690 break;
1691 case 2:
1692 if (len == 4)
1693 return 10;
1694 switch (read_u8(data, 4)) {
1695 case 0: vs->as.fmt = AUD_FMT_U8; break;
1696 case 1: vs->as.fmt = AUD_FMT_S8; break;
1697 case 2: vs->as.fmt = AUD_FMT_U16; break;
1698 case 3: vs->as.fmt = AUD_FMT_S16; break;
1699 case 4: vs->as.fmt = AUD_FMT_U32; break;
1700 case 5: vs->as.fmt = AUD_FMT_S32; break;
1701 default:
1702 printf("Invalid audio format %d\n", read_u8(data, 4));
1703 vnc_client_error(vs);
1704 break;
1706 vs->as.nchannels = read_u8(data, 5);
1707 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
1708 printf("Invalid audio channel coount %d\n",
1709 read_u8(data, 5));
1710 vnc_client_error(vs);
1711 break;
1713 vs->as.freq = read_u32(data, 6);
1714 break;
1715 default:
1716 printf ("Invalid audio message %d\n", read_u8(data, 4));
1717 vnc_client_error(vs);
1718 break;
1720 break;
1722 default:
1723 printf("Msg: %d\n", read_u16(data, 0));
1724 vnc_client_error(vs);
1725 break;
1727 break;
1728 default:
1729 printf("Msg: %d\n", data[0]);
1730 vnc_client_error(vs);
1731 break;
1734 vnc_read_when(vs, protocol_client_msg, 1);
1735 return 0;
1738 static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
1740 char buf[1024];
1741 int size;
1743 vnc_write_u16(vs, ds_get_width(vs->ds));
1744 vnc_write_u16(vs, ds_get_height(vs->ds));
1746 pixel_format_message(vs);
1748 if (qemu_name)
1749 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
1750 else
1751 size = snprintf(buf, sizeof(buf), "QEMU");
1753 vnc_write_u32(vs, size);
1754 vnc_write(vs, buf, size);
1755 vnc_flush(vs);
1757 vnc_read_when(vs, protocol_client_msg, 1);
1759 return 0;
1762 void start_client_init(VncState *vs)
1764 vnc_read_when(vs, protocol_client_init, 1);
1767 static void make_challenge(VncState *vs)
1769 int i;
1771 srand(time(NULL)+getpid()+getpid()*987654+rand());
1773 for (i = 0 ; i < sizeof(vs->challenge) ; i++)
1774 vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
1777 static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
1779 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
1780 int i, j, pwlen;
1781 unsigned char key[8];
1783 if (!vs->vd->password || !vs->vd->password[0]) {
1784 VNC_DEBUG("No password configured on server");
1785 vnc_write_u32(vs, 1); /* Reject auth */
1786 if (vs->minor >= 8) {
1787 static const char err[] = "Authentication failed";
1788 vnc_write_u32(vs, sizeof(err));
1789 vnc_write(vs, err, sizeof(err));
1791 vnc_flush(vs);
1792 vnc_client_error(vs);
1793 return 0;
1796 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
1798 /* Calculate the expected challenge response */
1799 pwlen = strlen(vs->vd->password);
1800 for (i=0; i<sizeof(key); i++)
1801 key[i] = i<pwlen ? vs->vd->password[i] : 0;
1802 deskey(key, EN0);
1803 for (j = 0; j < VNC_AUTH_CHALLENGE_SIZE; j += 8)
1804 des(response+j, response+j);
1806 /* Compare expected vs actual challenge response */
1807 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
1808 VNC_DEBUG("Client challenge reponse did not match\n");
1809 vnc_write_u32(vs, 1); /* Reject auth */
1810 if (vs->minor >= 8) {
1811 static const char err[] = "Authentication failed";
1812 vnc_write_u32(vs, sizeof(err));
1813 vnc_write(vs, err, sizeof(err));
1815 vnc_flush(vs);
1816 vnc_client_error(vs);
1817 } else {
1818 VNC_DEBUG("Accepting VNC challenge response\n");
1819 vnc_write_u32(vs, 0); /* Accept auth */
1820 vnc_flush(vs);
1822 start_client_init(vs);
1824 return 0;
1827 void start_auth_vnc(VncState *vs)
1829 make_challenge(vs);
1830 /* Send client a 'random' challenge */
1831 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
1832 vnc_flush(vs);
1834 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
1838 static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
1840 /* We only advertise 1 auth scheme at a time, so client
1841 * must pick the one we sent. Verify this */
1842 if (data[0] != vs->vd->auth) { /* Reject auth */
1843 VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
1844 vnc_write_u32(vs, 1);
1845 if (vs->minor >= 8) {
1846 static const char err[] = "Authentication failed";
1847 vnc_write_u32(vs, sizeof(err));
1848 vnc_write(vs, err, sizeof(err));
1850 vnc_client_error(vs);
1851 } else { /* Accept requested auth */
1852 VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
1853 switch (vs->vd->auth) {
1854 case VNC_AUTH_NONE:
1855 VNC_DEBUG("Accept auth none\n");
1856 if (vs->minor >= 8) {
1857 vnc_write_u32(vs, 0); /* Accept auth completion */
1858 vnc_flush(vs);
1860 start_client_init(vs);
1861 break;
1863 case VNC_AUTH_VNC:
1864 VNC_DEBUG("Start VNC auth\n");
1865 start_auth_vnc(vs);
1866 break;
1868 #ifdef CONFIG_VNC_TLS
1869 case VNC_AUTH_VENCRYPT:
1870 VNC_DEBUG("Accept VeNCrypt auth\n");;
1871 start_auth_vencrypt(vs);
1872 break;
1873 #endif /* CONFIG_VNC_TLS */
1875 #ifdef CONFIG_VNC_SASL
1876 case VNC_AUTH_SASL:
1877 VNC_DEBUG("Accept SASL auth\n");
1878 start_auth_sasl(vs);
1879 break;
1880 #endif /* CONFIG_VNC_SASL */
1882 default: /* Should not be possible, but just in case */
1883 VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth);
1884 vnc_write_u8(vs, 1);
1885 if (vs->minor >= 8) {
1886 static const char err[] = "Authentication failed";
1887 vnc_write_u32(vs, sizeof(err));
1888 vnc_write(vs, err, sizeof(err));
1890 vnc_client_error(vs);
1893 return 0;
1896 static int protocol_version(VncState *vs, uint8_t *version, size_t len)
1898 char local[13];
1900 memcpy(local, version, 12);
1901 local[12] = 0;
1903 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
1904 VNC_DEBUG("Malformed protocol version %s\n", local);
1905 vnc_client_error(vs);
1906 return 0;
1908 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
1909 if (vs->major != 3 ||
1910 (vs->minor != 3 &&
1911 vs->minor != 4 &&
1912 vs->minor != 5 &&
1913 vs->minor != 7 &&
1914 vs->minor != 8)) {
1915 VNC_DEBUG("Unsupported client version\n");
1916 vnc_write_u32(vs, VNC_AUTH_INVALID);
1917 vnc_flush(vs);
1918 vnc_client_error(vs);
1919 return 0;
1921 /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
1922 * as equivalent to v3.3 by servers
1924 if (vs->minor == 4 || vs->minor == 5)
1925 vs->minor = 3;
1927 if (vs->minor == 3) {
1928 if (vs->vd->auth == VNC_AUTH_NONE) {
1929 VNC_DEBUG("Tell client auth none\n");
1930 vnc_write_u32(vs, vs->vd->auth);
1931 vnc_flush(vs);
1932 start_client_init(vs);
1933 } else if (vs->vd->auth == VNC_AUTH_VNC) {
1934 VNC_DEBUG("Tell client VNC auth\n");
1935 vnc_write_u32(vs, vs->vd->auth);
1936 vnc_flush(vs);
1937 start_auth_vnc(vs);
1938 } else {
1939 VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
1940 vnc_write_u32(vs, VNC_AUTH_INVALID);
1941 vnc_flush(vs);
1942 vnc_client_error(vs);
1944 } else {
1945 VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
1946 vnc_write_u8(vs, 1); /* num auth */
1947 vnc_write_u8(vs, vs->vd->auth);
1948 vnc_read_when(vs, protocol_client_auth, 1);
1949 vnc_flush(vs);
1952 return 0;
1955 static void vnc_connect(VncDisplay *vd, int csock)
1957 VncState *vs = qemu_mallocz(sizeof(VncState));
1958 vs->csock = csock;
1960 VNC_DEBUG("New client on socket %d\n", csock);
1961 dcl->idle = 0;
1962 socket_set_nonblock(vs->csock);
1963 qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);
1965 vs->vd = vd;
1966 vs->ds = vd->ds;
1967 vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
1968 vs->last_x = -1;
1969 vs->last_y = -1;
1971 vs->as.freq = 44100;
1972 vs->as.nchannels = 2;
1973 vs->as.fmt = AUD_FMT_S16;
1974 vs->as.endianness = 0;
1976 vnc_resize(vs);
1977 vnc_write(vs, "RFB 003.008\n", 12);
1978 vnc_flush(vs);
1979 vnc_read_when(vs, protocol_version, 12);
1980 memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
1981 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
1982 vnc_update_client(vs);
1983 reset_keys(vs);
1985 vs->next = vd->clients;
1986 vd->clients = vs;
1989 static void vnc_listen_read(void *opaque)
1991 VncDisplay *vs = opaque;
1992 struct sockaddr_in addr;
1993 socklen_t addrlen = sizeof(addr);
1995 /* Catch-up */
1996 vga_hw_update();
1998 int csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
1999 if (csock != -1) {
2000 vnc_connect(vs, csock);
2004 void vnc_display_init(DisplayState *ds)
2006 VncDisplay *vs;
2008 vs = qemu_mallocz(sizeof(VncState));
2009 dcl = qemu_mallocz(sizeof(DisplayChangeListener));
2011 ds->opaque = vs;
2012 dcl->idle = 1;
2013 vnc_display = vs;
2015 vs->lsock = -1;
2017 vs->ds = ds;
2019 if (keyboard_layout)
2020 vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
2021 else
2022 vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
2024 if (!vs->kbd_layout)
2025 exit(1);
2027 dcl->dpy_copy = vnc_dpy_copy;
2028 dcl->dpy_update = vnc_dpy_update;
2029 dcl->dpy_resize = vnc_dpy_resize;
2030 dcl->dpy_setdata = vnc_dpy_setdata;
2031 register_displaychangelistener(ds, dcl);
2035 void vnc_display_close(DisplayState *ds)
2037 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2039 if (!vs)
2040 return;
2041 if (vs->display) {
2042 qemu_free(vs->display);
2043 vs->display = NULL;
2045 if (vs->lsock != -1) {
2046 qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
2047 close(vs->lsock);
2048 vs->lsock = -1;
2050 vs->auth = VNC_AUTH_INVALID;
2051 #ifdef CONFIG_VNC_TLS
2052 vs->subauth = VNC_AUTH_INVALID;
2053 vs->tls.x509verify = 0;
2054 #endif
2057 int vnc_display_password(DisplayState *ds, const char *password)
2059 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2061 if (vs->password) {
2062 qemu_free(vs->password);
2063 vs->password = NULL;
2065 if (password && password[0]) {
2066 if (!(vs->password = qemu_strdup(password)))
2067 return -1;
2070 return 0;
2073 int vnc_display_open(DisplayState *ds, const char *display)
2075 VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
2076 const char *options;
2077 int password = 0;
2078 int reverse = 0;
2079 int to_port = 0;
2080 #ifdef CONFIG_VNC_TLS
2081 int tls = 0, x509 = 0;
2082 #endif
2083 #ifdef CONFIG_VNC_SASL
2084 int sasl = 0;
2085 int saslErr;
2086 #endif
2087 int acl = 0;
2089 if (!vnc_display)
2090 return -1;
2091 vnc_display_close(ds);
2092 if (strcmp(display, "none") == 0)
2093 return 0;
2095 if (!(vs->display = strdup(display)))
2096 return -1;
2098 options = display;
2099 while ((options = strchr(options, ','))) {
2100 options++;
2101 if (strncmp(options, "password", 8) == 0) {
2102 password = 1; /* Require password auth */
2103 } else if (strncmp(options, "reverse", 7) == 0) {
2104 reverse = 1;
2105 } else if (strncmp(options, "to=", 3) == 0) {
2106 to_port = atoi(options+3) + 5900;
2107 #ifdef CONFIG_VNC_SASL
2108 } else if (strncmp(options, "sasl", 4) == 0) {
2109 sasl = 1; /* Require SASL auth */
2110 #endif
2111 #ifdef CONFIG_VNC_TLS
2112 } else if (strncmp(options, "tls", 3) == 0) {
2113 tls = 1; /* Require TLS */
2114 } else if (strncmp(options, "x509", 4) == 0) {
2115 char *start, *end;
2116 x509 = 1; /* Require x509 certificates */
2117 if (strncmp(options, "x509verify", 10) == 0)
2118 vs->tls.x509verify = 1; /* ...and verify client certs */
2120 /* Now check for 'x509=/some/path' postfix
2121 * and use that to setup x509 certificate/key paths */
2122 start = strchr(options, '=');
2123 end = strchr(options, ',');
2124 if (start && (!end || (start < end))) {
2125 int len = end ? end-(start+1) : strlen(start+1);
2126 char *path = qemu_strndup(start + 1, len);
2128 VNC_DEBUG("Trying certificate path '%s'\n", path);
2129 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
2130 fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
2131 qemu_free(path);
2132 qemu_free(vs->display);
2133 vs->display = NULL;
2134 return -1;
2136 qemu_free(path);
2137 } else {
2138 fprintf(stderr, "No certificate path provided\n");
2139 qemu_free(vs->display);
2140 vs->display = NULL;
2141 return -1;
2143 #endif
2144 } else if (strncmp(options, "acl", 3) == 0) {
2145 acl = 1;
2149 #ifdef CONFIG_VNC_TLS
2150 if (acl && x509 && vs->tls.x509verify) {
2151 if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
2152 fprintf(stderr, "Failed to create x509 dname ACL\n");
2153 exit(1);
2156 #endif
2157 #ifdef CONFIG_VNC_SASL
2158 if (acl && sasl) {
2159 if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
2160 fprintf(stderr, "Failed to create username ACL\n");
2161 exit(1);
2164 #endif
2167 * Combinations we support here:
2169 * - no-auth (clear text, no auth)
2170 * - password (clear text, weak auth)
2171 * - sasl (encrypt, good auth *IF* using Kerberos via GSSAPI)
2172 * - tls (encrypt, weak anonymous creds, no auth)
2173 * - tls + password (encrypt, weak anonymous creds, weak auth)
2174 * - tls + sasl (encrypt, weak anonymous creds, good auth)
2175 * - tls + x509 (encrypt, good x509 creds, no auth)
2176 * - tls + x509 + password (encrypt, good x509 creds, weak auth)
2177 * - tls + x509 + sasl (encrypt, good x509 creds, good auth)
2179 * NB1. TLS is a stackable auth scheme.
2180 * NB2. the x509 schemes have option to validate a client cert dname
2182 if (password) {
2183 #ifdef CONFIG_VNC_TLS
2184 if (tls) {
2185 vs->auth = VNC_AUTH_VENCRYPT;
2186 if (x509) {
2187 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
2188 vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
2189 } else {
2190 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
2191 vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
2193 } else {
2194 #endif /* CONFIG_VNC_TLS */
2195 VNC_DEBUG("Initializing VNC server with password auth\n");
2196 vs->auth = VNC_AUTH_VNC;
2197 #ifdef CONFIG_VNC_TLS
2198 vs->subauth = VNC_AUTH_INVALID;
2200 #endif /* CONFIG_VNC_TLS */
2201 #ifdef CONFIG_VNC_SASL
2202 } else if (sasl) {
2203 #ifdef CONFIG_VNC_TLS
2204 if (tls) {
2205 vs->auth = VNC_AUTH_VENCRYPT;
2206 if (x509) {
2207 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
2208 vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
2209 } else {
2210 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
2211 vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
2213 } else {
2214 #endif /* CONFIG_VNC_TLS */
2215 VNC_DEBUG("Initializing VNC server with SASL auth\n");
2216 vs->auth = VNC_AUTH_SASL;
2217 #ifdef CONFIG_VNC_TLS
2218 vs->subauth = VNC_AUTH_INVALID;
2220 #endif /* CONFIG_VNC_TLS */
2221 #endif /* CONFIG_VNC_SASL */
2222 } else {
2223 #ifdef CONFIG_VNC_TLS
2224 if (tls) {
2225 vs->auth = VNC_AUTH_VENCRYPT;
2226 if (x509) {
2227 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
2228 vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
2229 } else {
2230 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
2231 vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
2233 } else {
2234 #endif
2235 VNC_DEBUG("Initializing VNC server with no auth\n");
2236 vs->auth = VNC_AUTH_NONE;
2237 #ifdef CONFIG_VNC_TLS
2238 vs->subauth = VNC_AUTH_INVALID;
2240 #endif
2243 #ifdef CONFIG_VNC_SASL
2244 if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
2245 fprintf(stderr, "Failed to initialize SASL auth %s",
2246 sasl_errstring(saslErr, NULL, NULL));
2247 free(vs->display);
2248 vs->display = NULL;
2249 return -1;
2251 #endif
2253 if (reverse) {
2254 /* connect to viewer */
2255 if (strncmp(display, "unix:", 5) == 0)
2256 vs->lsock = unix_connect(display+5);
2257 else
2258 vs->lsock = inet_connect(display, SOCK_STREAM);
2259 if (-1 == vs->lsock) {
2260 free(vs->display);
2261 vs->display = NULL;
2262 return -1;
2263 } else {
2264 int csock = vs->lsock;
2265 vs->lsock = -1;
2266 vnc_connect(vs, csock);
2268 return 0;
2270 } else {
2271 /* listen for connects */
2272 char *dpy;
2273 dpy = qemu_malloc(256);
2274 if (strncmp(display, "unix:", 5) == 0) {
2275 pstrcpy(dpy, 256, "unix:");
2276 vs->lsock = unix_listen(display+5, dpy+5, 256-5);
2277 } else {
2278 vs->lsock = inet_listen(display, dpy, 256, SOCK_STREAM, 5900);
2280 if (-1 == vs->lsock) {
2281 free(dpy);
2282 return -1;
2283 } else {
2284 free(vs->display);
2285 vs->display = dpy;
2288 return qemu_set_fd_handler2(vs->lsock, NULL, vnc_listen_read, NULL, vs);