Annotation of qemu/vnc.c, revision 1.1.1.7

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

unix.superglobalmegacorp.com