Annotation of qemu/vnc.c, revision 1.1.1.11

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

unix.superglobalmegacorp.com