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