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