File:  [Qemu by Fabrice Bellard] / qemu / vnc.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:50:51 2018 UTC (3 years, 2 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0102, qemu0101, qemu0100, HEAD
qemu 0.10.0

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

unix.superglobalmegacorp.com