1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "qemu/osdep.h"
28#include "vnc.h"
29#include "vnc-jobs.h"
30#include "trace.h"
31#include "hw/qdev-core.h"
32#include "sysemu/sysemu.h"
33#include "sysemu/runstate.h"
34#include "qemu/error-report.h"
35#include "qemu/main-loop.h"
36#include "qemu/module.h"
37#include "qemu/option.h"
38#include "qemu/sockets.h"
39#include "qemu/timer.h"
40#include "authz/list.h"
41#include "qemu/config-file.h"
42#include "qapi/qapi-emit-events.h"
43#include "qapi/qapi-events-ui.h"
44#include "qapi/error.h"
45#include "qapi/qapi-commands-ui.h"
46#include "ui/input.h"
47#include "crypto/hash.h"
48#include "crypto/tlscreds.h"
49#include "crypto/tlscredsanon.h"
50#include "crypto/tlscredsx509.h"
51#include "crypto/random.h"
52#include "crypto/secret_common.h"
53#include "qom/object_interfaces.h"
54#include "qemu/cutils.h"
55#include "qemu/help_option.h"
56#include "io/dns-resolver.h"
57
58#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
59#define VNC_REFRESH_INTERVAL_INC 50
60#define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
61static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
62static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
63
64#include "vnc_keysym.h"
65#include "crypto/cipher.h"
66
67static QTAILQ_HEAD(, VncDisplay) vnc_displays =
68 QTAILQ_HEAD_INITIALIZER(vnc_displays);
69
70static int vnc_cursor_define(VncState *vs);
71static void vnc_update_throttle_offset(VncState *vs);
72
73static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
74{
75#ifdef _VNC_DEBUG
76 static const char *mn[] = {
77 [0] = "undefined",
78 [VNC_SHARE_MODE_CONNECTING] = "connecting",
79 [VNC_SHARE_MODE_SHARED] = "shared",
80 [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
81 [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
82 };
83 fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
84 vs->ioc, mn[vs->share_mode], mn[mode]);
85#endif
86
87 switch (vs->share_mode) {
88 case VNC_SHARE_MODE_CONNECTING:
89 vs->vd->num_connecting--;
90 break;
91 case VNC_SHARE_MODE_SHARED:
92 vs->vd->num_shared--;
93 break;
94 case VNC_SHARE_MODE_EXCLUSIVE:
95 vs->vd->num_exclusive--;
96 break;
97 default:
98 break;
99 }
100
101 vs->share_mode = mode;
102
103 switch (vs->share_mode) {
104 case VNC_SHARE_MODE_CONNECTING:
105 vs->vd->num_connecting++;
106 break;
107 case VNC_SHARE_MODE_SHARED:
108 vs->vd->num_shared++;
109 break;
110 case VNC_SHARE_MODE_EXCLUSIVE:
111 vs->vd->num_exclusive++;
112 break;
113 default:
114 break;
115 }
116}
117
118
119static void vnc_init_basic_info(SocketAddress *addr,
120 VncBasicInfo *info,
121 Error **errp)
122{
123 switch (addr->type) {
124 case SOCKET_ADDRESS_TYPE_INET:
125 info->host = g_strdup(addr->u.inet.host);
126 info->service = g_strdup(addr->u.inet.port);
127 if (addr->u.inet.ipv6) {
128 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
129 } else {
130 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
131 }
132 break;
133
134 case SOCKET_ADDRESS_TYPE_UNIX:
135 info->host = g_strdup("");
136 info->service = g_strdup(addr->u.q_unix.path);
137 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
138 break;
139
140 case SOCKET_ADDRESS_TYPE_VSOCK:
141 case SOCKET_ADDRESS_TYPE_FD:
142 error_setg(errp, "Unsupported socket address type %s",
143 SocketAddressType_str(addr->type));
144 break;
145 default:
146 abort();
147 }
148
149 return;
150}
151
152static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
153 VncBasicInfo *info,
154 Error **errp)
155{
156 SocketAddress *addr = NULL;
157
158 if (!ioc) {
159 error_setg(errp, "No listener socket available");
160 return;
161 }
162
163 addr = qio_channel_socket_get_local_address(ioc, errp);
164 if (!addr) {
165 return;
166 }
167
168 vnc_init_basic_info(addr, info, errp);
169 qapi_free_SocketAddress(addr);
170}
171
172static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
173 VncBasicInfo *info,
174 Error **errp)
175{
176 SocketAddress *addr = NULL;
177
178 addr = qio_channel_socket_get_remote_address(ioc, errp);
179 if (!addr) {
180 return;
181 }
182
183 vnc_init_basic_info(addr, info, errp);
184 qapi_free_SocketAddress(addr);
185}
186
187static const char *vnc_auth_name(VncDisplay *vd) {
188 switch (vd->auth) {
189 case VNC_AUTH_INVALID:
190 return "invalid";
191 case VNC_AUTH_NONE:
192 return "none";
193 case VNC_AUTH_VNC:
194 return "vnc";
195 case VNC_AUTH_RA2:
196 return "ra2";
197 case VNC_AUTH_RA2NE:
198 return "ra2ne";
199 case VNC_AUTH_TIGHT:
200 return "tight";
201 case VNC_AUTH_ULTRA:
202 return "ultra";
203 case VNC_AUTH_TLS:
204 return "tls";
205 case VNC_AUTH_VENCRYPT:
206 switch (vd->subauth) {
207 case VNC_AUTH_VENCRYPT_PLAIN:
208 return "vencrypt+plain";
209 case VNC_AUTH_VENCRYPT_TLSNONE:
210 return "vencrypt+tls+none";
211 case VNC_AUTH_VENCRYPT_TLSVNC:
212 return "vencrypt+tls+vnc";
213 case VNC_AUTH_VENCRYPT_TLSPLAIN:
214 return "vencrypt+tls+plain";
215 case VNC_AUTH_VENCRYPT_X509NONE:
216 return "vencrypt+x509+none";
217 case VNC_AUTH_VENCRYPT_X509VNC:
218 return "vencrypt+x509+vnc";
219 case VNC_AUTH_VENCRYPT_X509PLAIN:
220 return "vencrypt+x509+plain";
221 case VNC_AUTH_VENCRYPT_TLSSASL:
222 return "vencrypt+tls+sasl";
223 case VNC_AUTH_VENCRYPT_X509SASL:
224 return "vencrypt+x509+sasl";
225 default:
226 return "vencrypt";
227 }
228 case VNC_AUTH_SASL:
229 return "sasl";
230 }
231 return "unknown";
232}
233
234static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
235{
236 VncServerInfo *info;
237 Error *err = NULL;
238
239 if (!vd->listener || !vd->listener->nsioc) {
240 return NULL;
241 }
242
243 info = g_malloc0(sizeof(*info));
244 vnc_init_basic_info_from_server_addr(vd->listener->sioc[0],
245 qapi_VncServerInfo_base(info), &err);
246 info->has_auth = true;
247 info->auth = g_strdup(vnc_auth_name(vd));
248 if (err) {
249 qapi_free_VncServerInfo(info);
250 info = NULL;
251 error_free(err);
252 }
253 return info;
254}
255
256static void vnc_client_cache_auth(VncState *client)
257{
258 if (!client->info) {
259 return;
260 }
261
262 if (client->tls) {
263 client->info->x509_dname =
264 qcrypto_tls_session_get_peer_name(client->tls);
265 client->info->has_x509_dname =
266 client->info->x509_dname != NULL;
267 }
268#ifdef CONFIG_VNC_SASL
269 if (client->sasl.conn &&
270 client->sasl.username) {
271 client->info->has_sasl_username = true;
272 client->info->sasl_username = g_strdup(client->sasl.username);
273 }
274#endif
275}
276
277static void vnc_client_cache_addr(VncState *client)
278{
279 Error *err = NULL;
280
281 client->info = g_malloc0(sizeof(*client->info));
282 vnc_init_basic_info_from_remote_addr(client->sioc,
283 qapi_VncClientInfo_base(client->info),
284 &err);
285 client->info->websocket = client->websocket;
286 if (err) {
287 qapi_free_VncClientInfo(client->info);
288 client->info = NULL;
289 error_free(err);
290 }
291}
292
293static void vnc_qmp_event(VncState *vs, QAPIEvent event)
294{
295 VncServerInfo *si;
296
297 if (!vs->info) {
298 return;
299 }
300
301 si = vnc_server_info_get(vs->vd);
302 if (!si) {
303 return;
304 }
305
306 switch (event) {
307 case QAPI_EVENT_VNC_CONNECTED:
308 qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info));
309 break;
310 case QAPI_EVENT_VNC_INITIALIZED:
311 qapi_event_send_vnc_initialized(si, vs->info);
312 break;
313 case QAPI_EVENT_VNC_DISCONNECTED:
314 qapi_event_send_vnc_disconnected(si, vs->info);
315 break;
316 default:
317 break;
318 }
319
320 qapi_free_VncServerInfo(si);
321}
322
323static VncClientInfo *qmp_query_vnc_client(const VncState *client)
324{
325 VncClientInfo *info;
326 Error *err = NULL;
327
328 info = g_malloc0(sizeof(*info));
329
330 vnc_init_basic_info_from_remote_addr(client->sioc,
331 qapi_VncClientInfo_base(info),
332 &err);
333 if (err) {
334 error_free(err);
335 qapi_free_VncClientInfo(info);
336 return NULL;
337 }
338
339 info->websocket = client->websocket;
340
341 if (client->tls) {
342 info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
343 info->has_x509_dname = info->x509_dname != NULL;
344 }
345#ifdef CONFIG_VNC_SASL
346 if (client->sasl.conn && client->sasl.username) {
347 info->has_sasl_username = true;
348 info->sasl_username = g_strdup(client->sasl.username);
349 }
350#endif
351
352 return info;
353}
354
355static VncDisplay *vnc_display_find(const char *id)
356{
357 VncDisplay *vd;
358
359 if (id == NULL) {
360 return QTAILQ_FIRST(&vnc_displays);
361 }
362 QTAILQ_FOREACH(vd, &vnc_displays, next) {
363 if (strcmp(id, vd->id) == 0) {
364 return vd;
365 }
366 }
367 return NULL;
368}
369
370static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
371{
372 VncClientInfoList *prev = NULL;
373 VncState *client;
374
375 QTAILQ_FOREACH(client, &vd->clients, next) {
376 QAPI_LIST_PREPEND(prev, qmp_query_vnc_client(client));
377 }
378 return prev;
379}
380
381VncInfo *qmp_query_vnc(Error **errp)
382{
383 VncInfo *info = g_malloc0(sizeof(*info));
384 VncDisplay *vd = vnc_display_find(NULL);
385 SocketAddress *addr = NULL;
386
387 if (vd == NULL || !vd->listener || !vd->listener->nsioc) {
388 info->enabled = false;
389 } else {
390 info->enabled = true;
391
392
393 info->has_clients = true;
394 info->clients = qmp_query_client_list(vd);
395
396 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0],
397 errp);
398 if (!addr) {
399 goto out_error;
400 }
401
402 switch (addr->type) {
403 case SOCKET_ADDRESS_TYPE_INET:
404 info->host = g_strdup(addr->u.inet.host);
405 info->service = g_strdup(addr->u.inet.port);
406 if (addr->u.inet.ipv6) {
407 info->family = NETWORK_ADDRESS_FAMILY_IPV6;
408 } else {
409 info->family = NETWORK_ADDRESS_FAMILY_IPV4;
410 }
411 break;
412
413 case SOCKET_ADDRESS_TYPE_UNIX:
414 info->host = g_strdup("");
415 info->service = g_strdup(addr->u.q_unix.path);
416 info->family = NETWORK_ADDRESS_FAMILY_UNIX;
417 break;
418
419 case SOCKET_ADDRESS_TYPE_VSOCK:
420 case SOCKET_ADDRESS_TYPE_FD:
421 error_setg(errp, "Unsupported socket address type %s",
422 SocketAddressType_str(addr->type));
423 goto out_error;
424 default:
425 abort();
426 }
427
428 info->has_host = true;
429 info->has_service = true;
430 info->has_family = true;
431
432 info->has_auth = true;
433 info->auth = g_strdup(vnc_auth_name(vd));
434 }
435
436 qapi_free_SocketAddress(addr);
437 return info;
438
439out_error:
440 qapi_free_SocketAddress(addr);
441 qapi_free_VncInfo(info);
442 return NULL;
443}
444
445
446static void qmp_query_auth(int auth, int subauth,
447 VncPrimaryAuth *qmp_auth,
448 VncVencryptSubAuth *qmp_vencrypt,
449 bool *qmp_has_vencrypt);
450
451static VncServerInfo2List *qmp_query_server_entry(QIOChannelSocket *ioc,
452 bool websocket,
453 int auth,
454 int subauth,
455 VncServerInfo2List *prev)
456{
457 VncServerInfo2 *info;
458 Error *err = NULL;
459 SocketAddress *addr;
460
461 addr = qio_channel_socket_get_local_address(ioc, NULL);
462 if (!addr) {
463 return prev;
464 }
465
466 info = g_new0(VncServerInfo2, 1);
467 vnc_init_basic_info(addr, qapi_VncServerInfo2_base(info), &err);
468 qapi_free_SocketAddress(addr);
469 if (err) {
470 qapi_free_VncServerInfo2(info);
471 error_free(err);
472 return prev;
473 }
474 info->websocket = websocket;
475
476 qmp_query_auth(auth, subauth, &info->auth,
477 &info->vencrypt, &info->has_vencrypt);
478
479 QAPI_LIST_PREPEND(prev, info);
480 return prev;
481}
482
483static void qmp_query_auth(int auth, int subauth,
484 VncPrimaryAuth *qmp_auth,
485 VncVencryptSubAuth *qmp_vencrypt,
486 bool *qmp_has_vencrypt)
487{
488 switch (auth) {
489 case VNC_AUTH_VNC:
490 *qmp_auth = VNC_PRIMARY_AUTH_VNC;
491 break;
492 case VNC_AUTH_RA2:
493 *qmp_auth = VNC_PRIMARY_AUTH_RA2;
494 break;
495 case VNC_AUTH_RA2NE:
496 *qmp_auth = VNC_PRIMARY_AUTH_RA2NE;
497 break;
498 case VNC_AUTH_TIGHT:
499 *qmp_auth = VNC_PRIMARY_AUTH_TIGHT;
500 break;
501 case VNC_AUTH_ULTRA:
502 *qmp_auth = VNC_PRIMARY_AUTH_ULTRA;
503 break;
504 case VNC_AUTH_TLS:
505 *qmp_auth = VNC_PRIMARY_AUTH_TLS;
506 break;
507 case VNC_AUTH_VENCRYPT:
508 *qmp_auth = VNC_PRIMARY_AUTH_VENCRYPT;
509 *qmp_has_vencrypt = true;
510 switch (subauth) {
511 case VNC_AUTH_VENCRYPT_PLAIN:
512 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
513 break;
514 case VNC_AUTH_VENCRYPT_TLSNONE:
515 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
516 break;
517 case VNC_AUTH_VENCRYPT_TLSVNC:
518 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
519 break;
520 case VNC_AUTH_VENCRYPT_TLSPLAIN:
521 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
522 break;
523 case VNC_AUTH_VENCRYPT_X509NONE:
524 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
525 break;
526 case VNC_AUTH_VENCRYPT_X509VNC:
527 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
528 break;
529 case VNC_AUTH_VENCRYPT_X509PLAIN:
530 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
531 break;
532 case VNC_AUTH_VENCRYPT_TLSSASL:
533 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
534 break;
535 case VNC_AUTH_VENCRYPT_X509SASL:
536 *qmp_vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
537 break;
538 default:
539 *qmp_has_vencrypt = false;
540 break;
541 }
542 break;
543 case VNC_AUTH_SASL:
544 *qmp_auth = VNC_PRIMARY_AUTH_SASL;
545 break;
546 case VNC_AUTH_NONE:
547 default:
548 *qmp_auth = VNC_PRIMARY_AUTH_NONE;
549 break;
550 }
551}
552
553VncInfo2List *qmp_query_vnc_servers(Error **errp)
554{
555 VncInfo2List *prev = NULL;
556 VncInfo2 *info;
557 VncDisplay *vd;
558 DeviceState *dev;
559 size_t i;
560
561 QTAILQ_FOREACH(vd, &vnc_displays, next) {
562 info = g_new0(VncInfo2, 1);
563 info->id = g_strdup(vd->id);
564 info->clients = qmp_query_client_list(vd);
565 qmp_query_auth(vd->auth, vd->subauth, &info->auth,
566 &info->vencrypt, &info->has_vencrypt);
567 if (vd->dcl.con) {
568 dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
569 "device", &error_abort));
570 info->has_display = true;
571 info->display = g_strdup(dev->id);
572 }
573 for (i = 0; vd->listener != NULL && i < vd->listener->nsioc; i++) {
574 info->server = qmp_query_server_entry(
575 vd->listener->sioc[i], false, vd->auth, vd->subauth,
576 info->server);
577 }
578 for (i = 0; vd->wslistener != NULL && i < vd->wslistener->nsioc; i++) {
579 info->server = qmp_query_server_entry(
580 vd->wslistener->sioc[i], true, vd->ws_auth,
581 vd->ws_subauth, info->server);
582 }
583
584 QAPI_LIST_PREPEND(prev, info);
585 }
586 return prev;
587}
588
589bool vnc_display_reload_certs(const char *id, Error **errp)
590{
591 VncDisplay *vd = vnc_display_find(id);
592 QCryptoTLSCredsClass *creds = NULL;
593
594 if (!vd) {
595 error_setg(errp, "Can not find vnc display");
596 return false;
597 }
598
599 if (!vd->tlscreds) {
600 error_setg(errp, "vnc tls is not enable");
601 return false;
602 }
603
604 creds = QCRYPTO_TLS_CREDS_GET_CLASS(OBJECT(vd->tlscreds));
605 if (creds->reload == NULL) {
606 error_setg(errp, "%s doesn't support to reload TLS credential",
607 object_get_typename(OBJECT(vd->tlscreds)));
608 return false;
609 }
610 if (!creds->reload(vd->tlscreds, errp)) {
611 return false;
612 }
613
614 return true;
615}
616
617
618
619
620
621
622
623
624static int vnc_update_client(VncState *vs, int has_dirty);
625static void vnc_disconnect_start(VncState *vs);
626
627static void vnc_colordepth(VncState *vs);
628static void framebuffer_update_request(VncState *vs, int incremental,
629 int x_position, int y_position,
630 int w, int h);
631static void vnc_refresh(DisplayChangeListener *dcl);
632static int vnc_refresh_server_surface(VncDisplay *vd);
633
634static int vnc_width(VncDisplay *vd)
635{
636 return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
637 VNC_DIRTY_PIXELS_PER_BIT));
638}
639
640static int vnc_true_width(VncDisplay *vd)
641{
642 return MIN(VNC_MAX_WIDTH, surface_width(vd->ds));
643}
644
645static int vnc_height(VncDisplay *vd)
646{
647 return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
648}
649
650static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
651 VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
652 VncDisplay *vd,
653 int x, int y, int w, int h)
654{
655 int width = vnc_width(vd);
656 int height = vnc_height(vd);
657
658
659
660 w += (x % VNC_DIRTY_PIXELS_PER_BIT);
661 x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
662
663 x = MIN(x, width);
664 y = MIN(y, height);
665 w = MIN(x + w, width) - x;
666 h = MIN(y + h, height);
667
668 for (; y < h; y++) {
669 bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
670 DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
671 }
672}
673
674static void vnc_dpy_update(DisplayChangeListener *dcl,
675 int x, int y, int w, int h)
676{
677 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
678 struct VncSurface *s = &vd->guest;
679
680 vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
681}
682
683void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
684 int32_t encoding)
685{
686 vnc_write_u16(vs, x);
687 vnc_write_u16(vs, y);
688 vnc_write_u16(vs, w);
689 vnc_write_u16(vs, h);
690
691 vnc_write_s32(vs, encoding);
692}
693
694static void vnc_desktop_resize_ext(VncState *vs, int reject_reason)
695{
696 trace_vnc_msg_server_ext_desktop_resize(
697 vs, vs->ioc, vs->client_width, vs->client_height, reject_reason);
698
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);
703 vnc_framebuffer_update(vs,
704 reject_reason ? 1 : 0,
705 reject_reason,
706 vs->client_width, vs->client_height,
707 VNC_ENCODING_DESKTOP_RESIZE_EXT);
708 vnc_write_u8(vs, 1);
709 vnc_write_u8(vs, 0);
710 vnc_write_u8(vs, 0);
711 vnc_write_u8(vs, 0);
712 vnc_write_u32(vs, 0);
713 vnc_write_u16(vs, 0);
714 vnc_write_u16(vs, 0);
715 vnc_write_u16(vs, vs->client_width);
716 vnc_write_u16(vs, vs->client_height);
717 vnc_write_u32(vs, 0);
718 vnc_unlock_output(vs);
719 vnc_flush(vs);
720}
721
722static void vnc_desktop_resize(VncState *vs)
723{
724 if (vs->ioc == NULL || (!vnc_has_feature(vs, VNC_FEATURE_RESIZE) &&
725 !vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT))) {
726 return;
727 }
728 if (vs->client_width == vs->vd->true_width &&
729 vs->client_height == pixman_image_get_height(vs->vd->server)) {
730 return;
731 }
732
733 assert(vs->vd->true_width < 65536 &&
734 vs->vd->true_width >= 0);
735 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
736 pixman_image_get_height(vs->vd->server) >= 0);
737 vs->client_width = vs->vd->true_width;
738 vs->client_height = pixman_image_get_height(vs->vd->server);
739
740 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
741 vnc_desktop_resize_ext(vs, 0);
742 return;
743 }
744
745 trace_vnc_msg_server_desktop_resize(
746 vs, vs->ioc, vs->client_width, vs->client_height);
747
748 vnc_lock_output(vs);
749 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
750 vnc_write_u8(vs, 0);
751 vnc_write_u16(vs, 1);
752 vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
753 VNC_ENCODING_DESKTOPRESIZE);
754 vnc_unlock_output(vs);
755 vnc_flush(vs);
756}
757
758static void vnc_abort_display_jobs(VncDisplay *vd)
759{
760 VncState *vs;
761
762 QTAILQ_FOREACH(vs, &vd->clients, next) {
763 vnc_lock_output(vs);
764 vs->abort = true;
765 vnc_unlock_output(vs);
766 }
767 QTAILQ_FOREACH(vs, &vd->clients, next) {
768 vnc_jobs_join(vs);
769 }
770 QTAILQ_FOREACH(vs, &vd->clients, next) {
771 vnc_lock_output(vs);
772 if (vs->update == VNC_STATE_UPDATE_NONE &&
773 vs->job_update != VNC_STATE_UPDATE_NONE) {
774
775 vs->update = vs->job_update;
776 vs->job_update = VNC_STATE_UPDATE_NONE;
777 }
778 vs->abort = false;
779 vnc_unlock_output(vs);
780 }
781}
782
783int vnc_server_fb_stride(VncDisplay *vd)
784{
785 return pixman_image_get_stride(vd->server);
786}
787
788void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
789{
790 uint8_t *ptr;
791
792 ptr = (uint8_t *)pixman_image_get_data(vd->server);
793 ptr += y * vnc_server_fb_stride(vd);
794 ptr += x * VNC_SERVER_FB_BYTES;
795 return ptr;
796}
797
798static void vnc_update_server_surface(VncDisplay *vd)
799{
800 int width, height;
801
802 qemu_pixman_image_unref(vd->server);
803 vd->server = NULL;
804
805 if (QTAILQ_EMPTY(&vd->clients)) {
806 return;
807 }
808
809 width = vnc_width(vd);
810 height = vnc_height(vd);
811 vd->true_width = vnc_true_width(vd);
812 vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
813 width, height,
814 NULL, 0);
815
816 memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
817 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
818 width, height);
819}
820
821static bool vnc_check_pageflip(DisplaySurface *s1,
822 DisplaySurface *s2)
823{
824 return (s1 != NULL &&
825 s2 != NULL &&
826 surface_width(s1) == surface_width(s2) &&
827 surface_height(s1) == surface_height(s2) &&
828 surface_format(s1) == surface_format(s2));
829
830}
831
832static void vnc_dpy_switch(DisplayChangeListener *dcl,
833 DisplaySurface *surface)
834{
835 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
836 bool pageflip = vnc_check_pageflip(vd->ds, surface);
837 VncState *vs;
838
839 vnc_abort_display_jobs(vd);
840 vd->ds = surface;
841
842
843 qemu_pixman_image_unref(vd->guest.fb);
844 vd->guest.fb = pixman_image_ref(surface->image);
845 vd->guest.format = surface->format;
846
847
848 if (pageflip) {
849 trace_vnc_server_dpy_pageflip(vd,
850 surface_width(surface),
851 surface_height(surface),
852 surface_format(surface));
853 vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
854 surface_width(surface),
855 surface_height(surface));
856 return;
857 }
858
859 trace_vnc_server_dpy_recreate(vd,
860 surface_width(surface),
861 surface_height(surface),
862 surface_format(surface));
863
864 vnc_update_server_surface(vd);
865
866 QTAILQ_FOREACH(vs, &vd->clients, next) {
867 vnc_colordepth(vs);
868 vnc_desktop_resize(vs);
869 vnc_cursor_define(vs);
870 memset(vs->dirty, 0x00, sizeof(vs->dirty));
871 vnc_set_area_dirty(vs->dirty, vd, 0, 0,
872 vnc_width(vd),
873 vnc_height(vd));
874 vnc_update_throttle_offset(vs);
875 }
876}
877
878
879static void vnc_write_pixels_copy(VncState *vs,
880 void *pixels, int size)
881{
882 vnc_write(vs, pixels, size);
883}
884
885
886void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
887{
888 uint8_t r, g, b;
889
890#if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
891 r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
892 g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
893 b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
894#else
895# error need some bits here if you change VNC_SERVER_FB_FORMAT
896#endif
897 v = (r << vs->client_pf.rshift) |
898 (g << vs->client_pf.gshift) |
899 (b << vs->client_pf.bshift);
900 switch (vs->client_pf.bytes_per_pixel) {
901 case 1:
902 buf[0] = v;
903 break;
904 case 2:
905 if (vs->client_be) {
906 buf[0] = v >> 8;
907 buf[1] = v;
908 } else {
909 buf[1] = v >> 8;
910 buf[0] = v;
911 }
912 break;
913 default:
914 case 4:
915 if (vs->client_be) {
916 buf[0] = v >> 24;
917 buf[1] = v >> 16;
918 buf[2] = v >> 8;
919 buf[3] = v;
920 } else {
921 buf[3] = v >> 24;
922 buf[2] = v >> 16;
923 buf[1] = v >> 8;
924 buf[0] = v;
925 }
926 break;
927 }
928}
929
930static void vnc_write_pixels_generic(VncState *vs,
931 void *pixels1, int size)
932{
933 uint8_t buf[4];
934
935 if (VNC_SERVER_FB_BYTES == 4) {
936 uint32_t *pixels = pixels1;
937 int n, i;
938 n = size >> 2;
939 for (i = 0; i < n; i++) {
940 vnc_convert_pixel(vs, buf, pixels[i]);
941 vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
942 }
943 }
944}
945
946int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
947{
948 int i;
949 uint8_t *row;
950 VncDisplay *vd = vs->vd;
951
952 row = vnc_server_fb_ptr(vd, x, y);
953 for (i = 0; i < h; i++) {
954 vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
955 row += vnc_server_fb_stride(vd);
956 }
957 return 1;
958}
959
960int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
961{
962 int n = 0;
963
964 switch(vs->vnc_encoding) {
965 case VNC_ENCODING_ZLIB:
966 n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
967 break;
968 case VNC_ENCODING_HEXTILE:
969 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
970 n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
971 break;
972 case VNC_ENCODING_TIGHT:
973 n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
974 break;
975 case VNC_ENCODING_TIGHT_PNG:
976 n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
977 break;
978 case VNC_ENCODING_ZRLE:
979 n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
980 break;
981 case VNC_ENCODING_ZYWRLE:
982 n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
983 break;
984 default:
985 vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
986 n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
987 break;
988 }
989 return n;
990}
991
992static void vnc_mouse_set(DisplayChangeListener *dcl,
993 int x, int y, int visible)
994{
995
996}
997
998static int vnc_cursor_define(VncState *vs)
999{
1000 QEMUCursor *c = vs->vd->cursor;
1001 int isize;
1002
1003 if (!vs->vd->cursor) {
1004 return -1;
1005 }
1006
1007 if (vnc_has_feature(vs, VNC_FEATURE_ALPHA_CURSOR)) {
1008 vnc_lock_output(vs);
1009 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1010 vnc_write_u8(vs, 0);
1011 vnc_write_u16(vs, 1);
1012 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1013 VNC_ENCODING_ALPHA_CURSOR);
1014 vnc_write_s32(vs, VNC_ENCODING_RAW);
1015 vnc_write(vs, c->data, c->width * c->height * 4);
1016 vnc_unlock_output(vs);
1017 return 0;
1018 }
1019 if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
1020 vnc_lock_output(vs);
1021 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1022 vnc_write_u8(vs, 0);
1023 vnc_write_u16(vs, 1);
1024 vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
1025 VNC_ENCODING_RICH_CURSOR);
1026 isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
1027 vnc_write_pixels_generic(vs, c->data, isize);
1028 vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
1029 vnc_unlock_output(vs);
1030 return 0;
1031 }
1032 return -1;
1033}
1034
1035static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
1036 QEMUCursor *c)
1037{
1038 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
1039 VncState *vs;
1040
1041 cursor_put(vd->cursor);
1042 g_free(vd->cursor_mask);
1043
1044 vd->cursor = c;
1045 cursor_get(vd->cursor);
1046 vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
1047 vd->cursor_mask = g_malloc0(vd->cursor_msize);
1048 cursor_get_mono_mask(c, 0, vd->cursor_mask);
1049
1050 QTAILQ_FOREACH(vs, &vd->clients, next) {
1051 vnc_cursor_define(vs);
1052 }
1053}
1054
1055static int find_and_clear_dirty_height(VncState *vs,
1056 int y, int last_x, int x, int height)
1057{
1058 int h;
1059
1060 for (h = 1; h < (height - y); h++) {
1061 if (!test_bit(last_x, vs->dirty[y + h])) {
1062 break;
1063 }
1064 bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
1065 }
1066
1067 return h;
1068}
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080static void vnc_update_throttle_offset(VncState *vs)
1081{
1082 size_t offset =
1083 vs->client_width * vs->client_height * vs->client_pf.bytes_per_pixel;
1084
1085 if (vs->audio_cap) {
1086 int bps;
1087 switch (vs->as.fmt) {
1088 default:
1089 case AUDIO_FORMAT_U8:
1090 case AUDIO_FORMAT_S8:
1091 bps = 1;
1092 break;
1093 case AUDIO_FORMAT_U16:
1094 case AUDIO_FORMAT_S16:
1095 bps = 2;
1096 break;
1097 case AUDIO_FORMAT_U32:
1098 case AUDIO_FORMAT_S32:
1099 bps = 4;
1100 break;
1101 }
1102 offset += vs->as.freq * bps * vs->as.nchannels;
1103 }
1104
1105
1106
1107
1108
1109 offset = MAX(offset, 1024 * 1024);
1110
1111 if (vs->throttle_output_offset != offset) {
1112 trace_vnc_client_throttle_threshold(
1113 vs, vs->ioc, vs->throttle_output_offset, offset, vs->client_width,
1114 vs->client_height, vs->client_pf.bytes_per_pixel, vs->audio_cap);
1115 }
1116
1117 vs->throttle_output_offset = offset;
1118}
1119
1120static bool vnc_should_update(VncState *vs)
1121{
1122 switch (vs->update) {
1123 case VNC_STATE_UPDATE_NONE:
1124 break;
1125 case VNC_STATE_UPDATE_INCREMENTAL:
1126
1127
1128
1129
1130 if (vs->output.offset < vs->throttle_output_offset &&
1131 vs->job_update == VNC_STATE_UPDATE_NONE) {
1132 return true;
1133 }
1134 trace_vnc_client_throttle_incremental(
1135 vs, vs->ioc, vs->job_update, vs->output.offset);
1136 break;
1137 case VNC_STATE_UPDATE_FORCE:
1138
1139
1140
1141
1142
1143
1144
1145
1146 if (vs->force_update_offset == 0 &&
1147 vs->job_update == VNC_STATE_UPDATE_NONE) {
1148 return true;
1149 }
1150 trace_vnc_client_throttle_forced(
1151 vs, vs->ioc, vs->job_update, vs->force_update_offset);
1152 break;
1153 }
1154 return false;
1155}
1156
1157static int vnc_update_client(VncState *vs, int has_dirty)
1158{
1159 VncDisplay *vd = vs->vd;
1160 VncJob *job;
1161 int y;
1162 int height, width;
1163 int n = 0;
1164
1165 if (vs->disconnecting) {
1166 vnc_disconnect_finish(vs);
1167 return 0;
1168 }
1169
1170 vs->has_dirty += has_dirty;
1171 if (!vnc_should_update(vs)) {
1172 return 0;
1173 }
1174
1175 if (!vs->has_dirty && vs->update != VNC_STATE_UPDATE_FORCE) {
1176 return 0;
1177 }
1178
1179
1180
1181
1182
1183
1184
1185 job = vnc_job_new(vs);
1186
1187 height = pixman_image_get_height(vd->server);
1188 width = pixman_image_get_width(vd->server);
1189
1190 y = 0;
1191 for (;;) {
1192 int x, h;
1193 unsigned long x2;
1194 unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
1195 height * VNC_DIRTY_BPL(vs),
1196 y * VNC_DIRTY_BPL(vs));
1197 if (offset == height * VNC_DIRTY_BPL(vs)) {
1198
1199 break;
1200 }
1201 y = offset / VNC_DIRTY_BPL(vs);
1202 x = offset % VNC_DIRTY_BPL(vs);
1203 x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
1204 VNC_DIRTY_BPL(vs), x);
1205 bitmap_clear(vs->dirty[y], x, x2 - x);
1206 h = find_and_clear_dirty_height(vs, y, x, x2, height);
1207 x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
1208 if (x2 > x) {
1209 n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
1210 (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
1211 }
1212 if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
1213 y += h;
1214 if (y == height) {
1215 break;
1216 }
1217 }
1218 }
1219
1220 vs->job_update = vs->update;
1221 vs->update = VNC_STATE_UPDATE_NONE;
1222 vnc_job_push(job);
1223 vs->has_dirty = 0;
1224 return n;
1225}
1226
1227
1228static void audio_capture_notify(void *opaque, audcnotification_e cmd)
1229{
1230 VncState *vs = opaque;
1231
1232 assert(vs->magic == VNC_MAGIC);
1233 switch (cmd) {
1234 case AUD_CNOTIFY_DISABLE:
1235 trace_vnc_msg_server_audio_end(vs, vs->ioc);
1236 vnc_lock_output(vs);
1237 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1238 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1239 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
1240 vnc_unlock_output(vs);
1241 vnc_flush(vs);
1242 break;
1243
1244 case AUD_CNOTIFY_ENABLE:
1245 trace_vnc_msg_server_audio_begin(vs, vs->ioc);
1246 vnc_lock_output(vs);
1247 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1248 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1249 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
1250 vnc_unlock_output(vs);
1251 vnc_flush(vs);
1252 break;
1253 }
1254}
1255
1256static void audio_capture_destroy(void *opaque)
1257{
1258}
1259
1260static void audio_capture(void *opaque, const void *buf, int size)
1261{
1262 VncState *vs = opaque;
1263
1264 assert(vs->magic == VNC_MAGIC);
1265 trace_vnc_msg_server_audio_data(vs, vs->ioc, buf, size);
1266 vnc_lock_output(vs);
1267 if (vs->output.offset < vs->throttle_output_offset) {
1268 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
1269 vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
1270 vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
1271 vnc_write_u32(vs, size);
1272 vnc_write(vs, buf, size);
1273 } else {
1274 trace_vnc_client_throttle_audio(vs, vs->ioc, vs->output.offset);
1275 }
1276 vnc_unlock_output(vs);
1277 vnc_flush(vs);
1278}
1279
1280static void audio_add(VncState *vs)
1281{
1282 struct audio_capture_ops ops;
1283
1284 if (vs->audio_cap) {
1285 error_report("audio already running");
1286 return;
1287 }
1288
1289 ops.notify = audio_capture_notify;
1290 ops.destroy = audio_capture_destroy;
1291 ops.capture = audio_capture;
1292
1293 vs->audio_cap = AUD_add_capture(vs->vd->audio_state, &vs->as, &ops, vs);
1294 if (!vs->audio_cap) {
1295 error_report("Failed to add audio capture");
1296 }
1297}
1298
1299static void audio_del(VncState *vs)
1300{
1301 if (vs->audio_cap) {
1302 AUD_del_capture(vs->audio_cap, vs);
1303 vs->audio_cap = NULL;
1304 }
1305}
1306
1307static void vnc_disconnect_start(VncState *vs)
1308{
1309 if (vs->disconnecting) {
1310 return;
1311 }
1312 trace_vnc_client_disconnect_start(vs, vs->ioc);
1313 vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
1314 if (vs->ioc_tag) {
1315 g_source_remove(vs->ioc_tag);
1316 vs->ioc_tag = 0;
1317 }
1318 qio_channel_close(vs->ioc, NULL);
1319 vs->disconnecting = TRUE;
1320}
1321
1322void vnc_disconnect_finish(VncState *vs)
1323{
1324 int i;
1325
1326 trace_vnc_client_disconnect_finish(vs, vs->ioc);
1327
1328 vnc_jobs_join(vs);
1329
1330 vnc_lock_output(vs);
1331 vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
1332
1333 buffer_free(&vs->input);
1334 buffer_free(&vs->output);
1335
1336 qapi_free_VncClientInfo(vs->info);
1337
1338 vnc_zlib_clear(vs);
1339 vnc_tight_clear(vs);
1340 vnc_zrle_clear(vs);
1341
1342#ifdef CONFIG_VNC_SASL
1343 vnc_sasl_client_cleanup(vs);
1344#endif
1345 audio_del(vs);
1346 qkbd_state_lift_all_keys(vs->vd->kbd);
1347
1348 if (vs->mouse_mode_notifier.notify != NULL) {
1349 qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
1350 }
1351 QTAILQ_REMOVE(&vs->vd->clients, vs, next);
1352 if (QTAILQ_EMPTY(&vs->vd->clients)) {
1353
1354 vnc_update_server_surface(vs->vd);
1355 }
1356
1357 vnc_unlock_output(vs);
1358
1359 qemu_mutex_destroy(&vs->output_mutex);
1360 if (vs->bh != NULL) {
1361 qemu_bh_delete(vs->bh);
1362 }
1363 buffer_free(&vs->jobs_buffer);
1364
1365 for (i = 0; i < VNC_STAT_ROWS; ++i) {
1366 g_free(vs->lossy_rect[i]);
1367 }
1368 g_free(vs->lossy_rect);
1369
1370 object_unref(OBJECT(vs->ioc));
1371 vs->ioc = NULL;
1372 object_unref(OBJECT(vs->sioc));
1373 vs->sioc = NULL;
1374 vs->magic = 0;
1375 g_free(vs->zrle);
1376 g_free(vs->tight);
1377 g_free(vs);
1378}
1379
1380size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err)
1381{
1382 if (ret <= 0) {
1383 if (ret == 0) {
1384 trace_vnc_client_eof(vs, vs->ioc);
1385 vnc_disconnect_start(vs);
1386 } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
1387 trace_vnc_client_io_error(vs, vs->ioc,
1388 err ? error_get_pretty(err) : "Unknown");
1389 vnc_disconnect_start(vs);
1390 }
1391
1392 error_free(err);
1393 return 0;
1394 }
1395 return ret;
1396}
1397
1398
1399void vnc_client_error(VncState *vs)
1400{
1401 VNC_DEBUG("Closing down client sock: protocol error\n");
1402 vnc_disconnect_start(vs);
1403}
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421size_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
1422{
1423 Error *err = NULL;
1424 ssize_t ret;
1425 ret = qio_channel_write(vs->ioc, (const char *)data, datalen, &err);
1426 VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
1427 return vnc_client_io_error(vs, ret, err);
1428}
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441static size_t vnc_client_write_plain(VncState *vs)
1442{
1443 size_t offset;
1444 size_t ret;
1445
1446#ifdef CONFIG_VNC_SASL
1447 VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
1448 vs->output.buffer, vs->output.capacity, vs->output.offset,
1449 vs->sasl.waitWriteSSF);
1450
1451 if (vs->sasl.conn &&
1452 vs->sasl.runSSF &&
1453 vs->sasl.waitWriteSSF) {
1454 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
1455 if (ret)
1456 vs->sasl.waitWriteSSF -= ret;
1457 } else
1458#endif
1459 ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
1460 if (!ret)
1461 return 0;
1462
1463 if (ret >= vs->force_update_offset) {
1464 if (vs->force_update_offset != 0) {
1465 trace_vnc_client_unthrottle_forced(vs, vs->ioc);
1466 }
1467 vs->force_update_offset = 0;
1468 } else {
1469 vs->force_update_offset -= ret;
1470 }
1471 offset = vs->output.offset;
1472 buffer_advance(&vs->output, ret);
1473 if (offset >= vs->throttle_output_offset &&
1474 vs->output.offset < vs->throttle_output_offset) {
1475 trace_vnc_client_unthrottle_incremental(vs, vs->ioc, vs->output.offset);
1476 }
1477
1478 if (vs->output.offset == 0) {
1479 if (vs->ioc_tag) {
1480 g_source_remove(vs->ioc_tag);
1481 }
1482 vs->ioc_tag = qio_channel_add_watch(
1483 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1484 vnc_client_io, vs, NULL);
1485 }
1486
1487 return ret;
1488}
1489
1490
1491
1492
1493
1494
1495
1496static void vnc_client_write_locked(VncState *vs)
1497{
1498#ifdef CONFIG_VNC_SASL
1499 if (vs->sasl.conn &&
1500 vs->sasl.runSSF &&
1501 !vs->sasl.waitWriteSSF) {
1502 vnc_client_write_sasl(vs);
1503 } else
1504#endif
1505 {
1506 vnc_client_write_plain(vs);
1507 }
1508}
1509
1510static void vnc_client_write(VncState *vs)
1511{
1512 assert(vs->magic == VNC_MAGIC);
1513 vnc_lock_output(vs);
1514 if (vs->output.offset) {
1515 vnc_client_write_locked(vs);
1516 } else if (vs->ioc != NULL) {
1517 if (vs->ioc_tag) {
1518 g_source_remove(vs->ioc_tag);
1519 }
1520 vs->ioc_tag = qio_channel_add_watch(
1521 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
1522 vnc_client_io, vs, NULL);
1523 }
1524 vnc_unlock_output(vs);
1525}
1526
1527void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
1528{
1529 vs->read_handler = func;
1530 vs->read_handler_expect = expecting;
1531}
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549size_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
1550{
1551 ssize_t ret;
1552 Error *err = NULL;
1553 ret = qio_channel_read(vs->ioc, (char *)data, datalen, &err);
1554 VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
1555 return vnc_client_io_error(vs, ret, err);
1556}
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568static size_t vnc_client_read_plain(VncState *vs)
1569{
1570 size_t ret;
1571 VNC_DEBUG("Read plain %p size %zd offset %zd\n",
1572 vs->input.buffer, vs->input.capacity, vs->input.offset);
1573 buffer_reserve(&vs->input, 4096);
1574 ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
1575 if (!ret)
1576 return 0;
1577 vs->input.offset += ret;
1578 return ret;
1579}
1580
1581static void vnc_jobs_bh(void *opaque)
1582{
1583 VncState *vs = opaque;
1584
1585 assert(vs->magic == VNC_MAGIC);
1586 vnc_jobs_consume_buffer(vs);
1587}
1588
1589
1590
1591
1592
1593
1594
1595static int vnc_client_read(VncState *vs)
1596{
1597 size_t ret;
1598
1599#ifdef CONFIG_VNC_SASL
1600 if (vs->sasl.conn && vs->sasl.runSSF)
1601 ret = vnc_client_read_sasl(vs);
1602 else
1603#endif
1604 ret = vnc_client_read_plain(vs);
1605 if (!ret) {
1606 if (vs->disconnecting) {
1607 vnc_disconnect_finish(vs);
1608 return -1;
1609 }
1610 return 0;
1611 }
1612
1613 while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
1614 size_t len = vs->read_handler_expect;
1615 int ret;
1616
1617 ret = vs->read_handler(vs, vs->input.buffer, len);
1618 if (vs->disconnecting) {
1619 vnc_disconnect_finish(vs);
1620 return -1;
1621 }
1622
1623 if (!ret) {
1624 buffer_advance(&vs->input, len);
1625 } else {
1626 vs->read_handler_expect = ret;
1627 }
1628 }
1629 return 0;
1630}
1631
1632gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
1633 GIOCondition condition, void *opaque)
1634{
1635 VncState *vs = opaque;
1636
1637 assert(vs->magic == VNC_MAGIC);
1638
1639 if (condition & (G_IO_HUP | G_IO_ERR)) {
1640 vnc_disconnect_start(vs);
1641 return TRUE;
1642 }
1643
1644 if (condition & G_IO_IN) {
1645 if (vnc_client_read(vs) < 0) {
1646
1647 return TRUE;
1648 }
1649 }
1650 if (condition & G_IO_OUT) {
1651 vnc_client_write(vs);
1652 }
1653
1654 if (vs->disconnecting) {
1655 if (vs->ioc_tag != 0) {
1656 g_source_remove(vs->ioc_tag);
1657 }
1658 vs->ioc_tag = 0;
1659 }
1660 return TRUE;
1661}
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671#define VNC_THROTTLE_OUTPUT_LIMIT_SCALE 5
1672
1673void vnc_write(VncState *vs, const void *data, size_t len)
1674{
1675 assert(vs->magic == VNC_MAGIC);
1676 if (vs->disconnecting) {
1677 return;
1678 }
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690 if (vs->throttle_output_offset != 0 &&
1691 (vs->output.offset / VNC_THROTTLE_OUTPUT_LIMIT_SCALE) >
1692 vs->throttle_output_offset) {
1693 trace_vnc_client_output_limit(vs, vs->ioc, vs->output.offset,
1694 vs->throttle_output_offset);
1695 vnc_disconnect_start(vs);
1696 return;
1697 }
1698 buffer_reserve(&vs->output, len);
1699
1700 if (vs->ioc != NULL && buffer_empty(&vs->output)) {
1701 if (vs->ioc_tag) {
1702 g_source_remove(vs->ioc_tag);
1703 }
1704 vs->ioc_tag = qio_channel_add_watch(
1705 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_OUT,
1706 vnc_client_io, vs, NULL);
1707 }
1708
1709 buffer_append(&vs->output, data, len);
1710}
1711
1712void vnc_write_s32(VncState *vs, int32_t value)
1713{
1714 vnc_write_u32(vs, *(uint32_t *)&value);
1715}
1716
1717void vnc_write_u32(VncState *vs, uint32_t value)
1718{
1719 uint8_t buf[4];
1720
1721 buf[0] = (value >> 24) & 0xFF;
1722 buf[1] = (value >> 16) & 0xFF;
1723 buf[2] = (value >> 8) & 0xFF;
1724 buf[3] = value & 0xFF;
1725
1726 vnc_write(vs, buf, 4);
1727}
1728
1729void vnc_write_u16(VncState *vs, uint16_t value)
1730{
1731 uint8_t buf[2];
1732
1733 buf[0] = (value >> 8) & 0xFF;
1734 buf[1] = value & 0xFF;
1735
1736 vnc_write(vs, buf, 2);
1737}
1738
1739void vnc_write_u8(VncState *vs, uint8_t value)
1740{
1741 vnc_write(vs, (char *)&value, 1);
1742}
1743
1744void vnc_flush(VncState *vs)
1745{
1746 vnc_lock_output(vs);
1747 if (vs->ioc != NULL && vs->output.offset) {
1748 vnc_client_write_locked(vs);
1749 }
1750 if (vs->disconnecting) {
1751 if (vs->ioc_tag != 0) {
1752 g_source_remove(vs->ioc_tag);
1753 }
1754 vs->ioc_tag = 0;
1755 }
1756 vnc_unlock_output(vs);
1757}
1758
1759static uint8_t read_u8(uint8_t *data, size_t offset)
1760{
1761 return data[offset];
1762}
1763
1764static uint16_t read_u16(uint8_t *data, size_t offset)
1765{
1766 return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
1767}
1768
1769static int32_t read_s32(uint8_t *data, size_t offset)
1770{
1771 return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
1772 (data[offset + 2] << 8) | data[offset + 3]);
1773}
1774
1775uint32_t read_u32(uint8_t *data, size_t offset)
1776{
1777 return ((data[offset] << 24) | (data[offset + 1] << 16) |
1778 (data[offset + 2] << 8) | data[offset + 3]);
1779}
1780
1781static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
1782{
1783}
1784
1785static void check_pointer_type_change(Notifier *notifier, void *data)
1786{
1787 VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
1788 int absolute = qemu_input_is_absolute();
1789
1790 if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
1791 vnc_lock_output(vs);
1792 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1793 vnc_write_u8(vs, 0);
1794 vnc_write_u16(vs, 1);
1795 vnc_framebuffer_update(vs, absolute, 0,
1796 pixman_image_get_width(vs->vd->server),
1797 pixman_image_get_height(vs->vd->server),
1798 VNC_ENCODING_POINTER_TYPE_CHANGE);
1799 vnc_unlock_output(vs);
1800 vnc_flush(vs);
1801 }
1802 vs->absolute = absolute;
1803}
1804
1805static void pointer_event(VncState *vs, int button_mask, int x, int y)
1806{
1807 static uint32_t bmap[INPUT_BUTTON__MAX] = {
1808 [INPUT_BUTTON_LEFT] = 0x01,
1809 [INPUT_BUTTON_MIDDLE] = 0x02,
1810 [INPUT_BUTTON_RIGHT] = 0x04,
1811 [INPUT_BUTTON_WHEEL_UP] = 0x08,
1812 [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
1813 };
1814 QemuConsole *con = vs->vd->dcl.con;
1815 int width = pixman_image_get_width(vs->vd->server);
1816 int height = pixman_image_get_height(vs->vd->server);
1817
1818 if (vs->last_bmask != button_mask) {
1819 qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
1820 vs->last_bmask = button_mask;
1821 }
1822
1823 if (vs->absolute) {
1824 qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
1825 qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
1826 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
1827 qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
1828 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
1829 } else {
1830 if (vs->last_x != -1) {
1831 qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
1832 qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
1833 }
1834 vs->last_x = x;
1835 vs->last_y = y;
1836 }
1837 qemu_input_event_sync();
1838}
1839
1840static void press_key(VncState *vs, QKeyCode qcode)
1841{
1842 qkbd_state_key_event(vs->vd->kbd, qcode, true);
1843 qkbd_state_key_event(vs->vd->kbd, qcode, false);
1844}
1845
1846static void vnc_led_state_change(VncState *vs)
1847{
1848 if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
1849 return;
1850 }
1851
1852 vnc_lock_output(vs);
1853 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
1854 vnc_write_u8(vs, 0);
1855 vnc_write_u16(vs, 1);
1856 vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
1857 vnc_write_u8(vs, vs->vd->ledstate);
1858 vnc_unlock_output(vs);
1859 vnc_flush(vs);
1860}
1861
1862static void kbd_leds(void *opaque, int ledstate)
1863{
1864 VncDisplay *vd = opaque;
1865 VncState *client;
1866
1867 trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
1868 (ledstate & QEMU_NUM_LOCK_LED),
1869 (ledstate & QEMU_SCROLL_LOCK_LED));
1870
1871 if (ledstate == vd->ledstate) {
1872 return;
1873 }
1874
1875 vd->ledstate = ledstate;
1876
1877 QTAILQ_FOREACH(client, &vd->clients, next) {
1878 vnc_led_state_change(client);
1879 }
1880}
1881
1882static void do_key_event(VncState *vs, int down, int keycode, int sym)
1883{
1884 QKeyCode qcode = qemu_input_key_number_to_qcode(keycode);
1885
1886
1887 switch (qcode) {
1888 case Q_KEY_CODE_1 ... Q_KEY_CODE_9:
1889 if (vs->vd->dcl.con == NULL && down &&
1890 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL) &&
1891 qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {
1892
1893 qkbd_state_lift_all_keys(vs->vd->kbd);
1894 console_select(qcode - Q_KEY_CODE_1);
1895 return;
1896 }
1897 default:
1898 break;
1899 }
1900
1901
1902
1903
1904 if (down && vs->vd->lock_key_sync &&
1905 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1906 keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
1907
1908
1909
1910
1911 if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
1912 if (!qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1913 trace_vnc_key_sync_numlock(true);
1914 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1915 }
1916 } else {
1917 if (qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK)) {
1918 trace_vnc_key_sync_numlock(false);
1919 press_key(vs, Q_KEY_CODE_NUM_LOCK);
1920 }
1921 }
1922 }
1923
1924 if (down && vs->vd->lock_key_sync &&
1925 !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
1926 ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
1927
1928
1929
1930
1931 int uppercase = !!(sym >= 'A' && sym <= 'Z');
1932 bool shift = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_SHIFT);
1933 bool capslock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CAPSLOCK);
1934 if (capslock) {
1935 if (uppercase == shift) {
1936 trace_vnc_key_sync_capslock(false);
1937 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1938 }
1939 } else {
1940 if (uppercase != shift) {
1941 trace_vnc_key_sync_capslock(true);
1942 press_key(vs, Q_KEY_CODE_CAPS_LOCK);
1943 }
1944 }
1945 }
1946
1947 qkbd_state_key_event(vs->vd->kbd, qcode, down);
1948 if (!qemu_console_is_graphic(NULL)) {
1949 bool numlock = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_NUMLOCK);
1950 bool control = qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_CTRL);
1951
1952 if (down) {
1953 switch (keycode) {
1954 case 0x2a:
1955 case 0x36:
1956 case 0x1d:
1957 case 0x9d:
1958 case 0x38:
1959 case 0xb8:
1960 break;
1961 case 0xc8:
1962 kbd_put_keysym(QEMU_KEY_UP);
1963 break;
1964 case 0xd0:
1965 kbd_put_keysym(QEMU_KEY_DOWN);
1966 break;
1967 case 0xcb:
1968 kbd_put_keysym(QEMU_KEY_LEFT);
1969 break;
1970 case 0xcd:
1971 kbd_put_keysym(QEMU_KEY_RIGHT);
1972 break;
1973 case 0xd3:
1974 kbd_put_keysym(QEMU_KEY_DELETE);
1975 break;
1976 case 0xc7:
1977 kbd_put_keysym(QEMU_KEY_HOME);
1978 break;
1979 case 0xcf:
1980 kbd_put_keysym(QEMU_KEY_END);
1981 break;
1982 case 0xc9:
1983 kbd_put_keysym(QEMU_KEY_PAGEUP);
1984 break;
1985 case 0xd1:
1986 kbd_put_keysym(QEMU_KEY_PAGEDOWN);
1987 break;
1988
1989 case 0x47:
1990 kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
1991 break;
1992 case 0x48:
1993 kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
1994 break;
1995 case 0x49:
1996 kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
1997 break;
1998 case 0x4b:
1999 kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
2000 break;
2001 case 0x4c:
2002 kbd_put_keysym('5');
2003 break;
2004 case 0x4d:
2005 kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
2006 break;
2007 case 0x4f:
2008 kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
2009 break;
2010 case 0x50:
2011 kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
2012 break;
2013 case 0x51:
2014 kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
2015 break;
2016 case 0x52:
2017 kbd_put_keysym('0');
2018 break;
2019 case 0x53:
2020 kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
2021 break;
2022
2023 case 0xb5:
2024 kbd_put_keysym('/');
2025 break;
2026 case 0x37:
2027 kbd_put_keysym('*');
2028 break;
2029 case 0x4a:
2030 kbd_put_keysym('-');
2031 break;
2032 case 0x4e:
2033 kbd_put_keysym('+');
2034 break;
2035 case 0x9c:
2036 kbd_put_keysym('\n');
2037 break;
2038
2039 default:
2040 if (control) {
2041 kbd_put_keysym(sym & 0x1f);
2042 } else {
2043 kbd_put_keysym(sym);
2044 }
2045 break;
2046 }
2047 }
2048 }
2049}
2050
2051static const char *code2name(int keycode)
2052{
2053 return QKeyCode_str(qemu_input_key_number_to_qcode(keycode));
2054}
2055
2056static void key_event(VncState *vs, int down, uint32_t sym)
2057{
2058 int keycode;
2059 int lsym = sym;
2060
2061 if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
2062 lsym = lsym - 'A' + 'a';
2063 }
2064
2065 keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF,
2066 vs->vd->kbd, down) & SCANCODE_KEYMASK;
2067 trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
2068 do_key_event(vs, down, keycode, sym);
2069}
2070
2071static void ext_key_event(VncState *vs, int down,
2072 uint32_t sym, uint16_t keycode)
2073{
2074
2075 if (keyboard_layout) {
2076 key_event(vs, down, sym);
2077 } else {
2078 trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
2079 do_key_event(vs, down, keycode, sym);
2080 }
2081}
2082
2083static void framebuffer_update_request(VncState *vs, int incremental,
2084 int x, int y, int w, int h)
2085{
2086 if (incremental) {
2087 if (vs->update != VNC_STATE_UPDATE_FORCE) {
2088 vs->update = VNC_STATE_UPDATE_INCREMENTAL;
2089 }
2090 } else {
2091 vs->update = VNC_STATE_UPDATE_FORCE;
2092 vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
2093 if (vnc_has_feature(vs, VNC_FEATURE_RESIZE_EXT)) {
2094 vnc_desktop_resize_ext(vs, 0);
2095 }
2096 }
2097}
2098
2099static void send_ext_key_event_ack(VncState *vs)
2100{
2101 vnc_lock_output(vs);
2102 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2103 vnc_write_u8(vs, 0);
2104 vnc_write_u16(vs, 1);
2105 vnc_framebuffer_update(vs, 0, 0,
2106 pixman_image_get_width(vs->vd->server),
2107 pixman_image_get_height(vs->vd->server),
2108 VNC_ENCODING_EXT_KEY_EVENT);
2109 vnc_unlock_output(vs);
2110 vnc_flush(vs);
2111}
2112
2113static void send_ext_audio_ack(VncState *vs)
2114{
2115 vnc_lock_output(vs);
2116 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2117 vnc_write_u8(vs, 0);
2118 vnc_write_u16(vs, 1);
2119 vnc_framebuffer_update(vs, 0, 0,
2120 pixman_image_get_width(vs->vd->server),
2121 pixman_image_get_height(vs->vd->server),
2122 VNC_ENCODING_AUDIO);
2123 vnc_unlock_output(vs);
2124 vnc_flush(vs);
2125}
2126
2127static void send_xvp_message(VncState *vs, int code)
2128{
2129 vnc_lock_output(vs);
2130 vnc_write_u8(vs, VNC_MSG_SERVER_XVP);
2131 vnc_write_u8(vs, 0);
2132 vnc_write_u8(vs, 1);
2133 vnc_write_u8(vs, code);
2134 vnc_unlock_output(vs);
2135 vnc_flush(vs);
2136}
2137
2138static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
2139{
2140 int i;
2141 unsigned int enc = 0;
2142
2143 vs->features = 0;
2144 vs->vnc_encoding = 0;
2145 vs->tight->compression = 9;
2146 vs->tight->quality = -1;
2147 vs->absolute = -1;
2148
2149
2150
2151
2152
2153
2154 for (i = n_encodings - 1; i >= 0; i--) {
2155 enc = encodings[i];
2156 switch (enc) {
2157 case VNC_ENCODING_RAW:
2158 vs->vnc_encoding = enc;
2159 break;
2160 case VNC_ENCODING_HEXTILE:
2161 vs->features |= VNC_FEATURE_HEXTILE_MASK;
2162 vs->vnc_encoding = enc;
2163 break;
2164 case VNC_ENCODING_TIGHT:
2165 vs->features |= VNC_FEATURE_TIGHT_MASK;
2166 vs->vnc_encoding = enc;
2167 break;
2168#ifdef CONFIG_VNC_PNG
2169 case VNC_ENCODING_TIGHT_PNG:
2170 vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
2171 vs->vnc_encoding = enc;
2172 break;
2173#endif
2174 case VNC_ENCODING_ZLIB:
2175
2176
2177
2178
2179
2180 if ((vs->features & VNC_FEATURE_ZRLE_MASK) == 0) {
2181 vs->features |= VNC_FEATURE_ZLIB_MASK;
2182 vs->vnc_encoding = enc;
2183 }
2184 break;
2185 case VNC_ENCODING_ZRLE:
2186 vs->features |= VNC_FEATURE_ZRLE_MASK;
2187 vs->vnc_encoding = enc;
2188 break;
2189 case VNC_ENCODING_ZYWRLE:
2190 vs->features |= VNC_FEATURE_ZYWRLE_MASK;
2191 vs->vnc_encoding = enc;
2192 break;
2193 case VNC_ENCODING_DESKTOPRESIZE:
2194 vs->features |= VNC_FEATURE_RESIZE_MASK;
2195 break;
2196 case VNC_ENCODING_DESKTOP_RESIZE_EXT:
2197 vs->features |= VNC_FEATURE_RESIZE_EXT_MASK;
2198 break;
2199 case VNC_ENCODING_POINTER_TYPE_CHANGE:
2200 vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
2201 break;
2202 case VNC_ENCODING_RICH_CURSOR:
2203 vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
2204 break;
2205 case VNC_ENCODING_ALPHA_CURSOR:
2206 vs->features |= VNC_FEATURE_ALPHA_CURSOR_MASK;
2207 break;
2208 case VNC_ENCODING_EXT_KEY_EVENT:
2209 send_ext_key_event_ack(vs);
2210 break;
2211 case VNC_ENCODING_AUDIO:
2212 send_ext_audio_ack(vs);
2213 break;
2214 case VNC_ENCODING_WMVi:
2215 vs->features |= VNC_FEATURE_WMVI_MASK;
2216 break;
2217 case VNC_ENCODING_LED_STATE:
2218 vs->features |= VNC_FEATURE_LED_STATE_MASK;
2219 break;
2220 case VNC_ENCODING_XVP:
2221 if (vs->vd->power_control) {
2222 vs->features |= VNC_FEATURE_XVP;
2223 send_xvp_message(vs, VNC_XVP_CODE_INIT);
2224 }
2225 break;
2226 case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
2227 vs->tight->compression = (enc & 0x0F);
2228 break;
2229 case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
2230 if (vs->vd->lossy) {
2231 vs->tight->quality = (enc & 0x0F);
2232 }
2233 break;
2234 default:
2235 VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
2236 break;
2237 }
2238 }
2239 vnc_desktop_resize(vs);
2240 check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
2241 vnc_led_state_change(vs);
2242 vnc_cursor_define(vs);
2243}
2244
2245static void set_pixel_conversion(VncState *vs)
2246{
2247 pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
2248
2249 if (fmt == VNC_SERVER_FB_FORMAT) {
2250 vs->write_pixels = vnc_write_pixels_copy;
2251 vnc_hextile_set_pixel_conversion(vs, 0);
2252 } else {
2253 vs->write_pixels = vnc_write_pixels_generic;
2254 vnc_hextile_set_pixel_conversion(vs, 1);
2255 }
2256}
2257
2258static void send_color_map(VncState *vs)
2259{
2260 int i;
2261
2262 vnc_lock_output(vs);
2263 vnc_write_u8(vs, VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES);
2264 vnc_write_u8(vs, 0);
2265 vnc_write_u16(vs, 0);
2266 vnc_write_u16(vs, 256);
2267
2268 for (i = 0; i < 256; i++) {
2269 PixelFormat *pf = &vs->client_pf;
2270
2271 vnc_write_u16(vs, (((i >> pf->rshift) & pf->rmax) << (16 - pf->rbits)));
2272 vnc_write_u16(vs, (((i >> pf->gshift) & pf->gmax) << (16 - pf->gbits)));
2273 vnc_write_u16(vs, (((i >> pf->bshift) & pf->bmax) << (16 - pf->bbits)));
2274 }
2275 vnc_unlock_output(vs);
2276}
2277
2278static void set_pixel_format(VncState *vs, int bits_per_pixel,
2279 int big_endian_flag, int true_color_flag,
2280 int red_max, int green_max, int blue_max,
2281 int red_shift, int green_shift, int blue_shift)
2282{
2283 if (!true_color_flag) {
2284
2285 bits_per_pixel = 8;
2286 red_max = 7;
2287 green_max = 7;
2288 blue_max = 3;
2289 red_shift = 0;
2290 green_shift = 3;
2291 blue_shift = 6;
2292 }
2293
2294 switch (bits_per_pixel) {
2295 case 8:
2296 case 16:
2297 case 32:
2298 break;
2299 default:
2300 vnc_client_error(vs);
2301 return;
2302 }
2303
2304 vs->client_pf.rmax = red_max ? red_max : 0xFF;
2305 vs->client_pf.rbits = ctpopl(red_max);
2306 vs->client_pf.rshift = red_shift;
2307 vs->client_pf.rmask = red_max << red_shift;
2308 vs->client_pf.gmax = green_max ? green_max : 0xFF;
2309 vs->client_pf.gbits = ctpopl(green_max);
2310 vs->client_pf.gshift = green_shift;
2311 vs->client_pf.gmask = green_max << green_shift;
2312 vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
2313 vs->client_pf.bbits = ctpopl(blue_max);
2314 vs->client_pf.bshift = blue_shift;
2315 vs->client_pf.bmask = blue_max << blue_shift;
2316 vs->client_pf.bits_per_pixel = bits_per_pixel;
2317 vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
2318 vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
2319 vs->client_be = big_endian_flag;
2320
2321 if (!true_color_flag) {
2322 send_color_map(vs);
2323 }
2324
2325 set_pixel_conversion(vs);
2326
2327 graphic_hw_invalidate(vs->vd->dcl.con);
2328 graphic_hw_update(vs->vd->dcl.con);
2329}
2330
2331static void pixel_format_message (VncState *vs) {
2332 char pad[3] = { 0, 0, 0 };
2333
2334 vs->client_pf = qemu_default_pixelformat(32);
2335
2336 vnc_write_u8(vs, vs->client_pf.bits_per_pixel);
2337 vnc_write_u8(vs, vs->client_pf.depth);
2338
2339#ifdef HOST_WORDS_BIGENDIAN
2340 vnc_write_u8(vs, 1);
2341#else
2342 vnc_write_u8(vs, 0);
2343#endif
2344 vnc_write_u8(vs, 1);
2345 vnc_write_u16(vs, vs->client_pf.rmax);
2346 vnc_write_u16(vs, vs->client_pf.gmax);
2347 vnc_write_u16(vs, vs->client_pf.bmax);
2348 vnc_write_u8(vs, vs->client_pf.rshift);
2349 vnc_write_u8(vs, vs->client_pf.gshift);
2350 vnc_write_u8(vs, vs->client_pf.bshift);
2351 vnc_write(vs, pad, 3);
2352
2353 vnc_hextile_set_pixel_conversion(vs, 0);
2354 vs->write_pixels = vnc_write_pixels_copy;
2355}
2356
2357static void vnc_colordepth(VncState *vs)
2358{
2359 if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
2360
2361 vnc_lock_output(vs);
2362 vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
2363 vnc_write_u8(vs, 0);
2364 vnc_write_u16(vs, 1);
2365 vnc_framebuffer_update(vs, 0, 0,
2366 vs->client_width,
2367 vs->client_height,
2368 VNC_ENCODING_WMVi);
2369 pixel_format_message(vs);
2370 vnc_unlock_output(vs);
2371 vnc_flush(vs);
2372 } else {
2373 set_pixel_conversion(vs);
2374 }
2375}
2376
2377static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
2378{
2379 int i;
2380 uint16_t limit;
2381 uint32_t freq;
2382 VncDisplay *vd = vs->vd;
2383
2384 if (data[0] > 3) {
2385 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
2386 }
2387
2388 switch (data[0]) {
2389 case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
2390 if (len == 1)
2391 return 20;
2392
2393 set_pixel_format(vs, read_u8(data, 4),
2394 read_u8(data, 6), read_u8(data, 7),
2395 read_u16(data, 8), read_u16(data, 10),
2396 read_u16(data, 12), read_u8(data, 14),
2397 read_u8(data, 15), read_u8(data, 16));
2398 break;
2399 case VNC_MSG_CLIENT_SET_ENCODINGS:
2400 if (len == 1)
2401 return 4;
2402
2403 if (len == 4) {
2404 limit = read_u16(data, 2);
2405 if (limit > 0)
2406 return 4 + (limit * 4);
2407 } else
2408 limit = read_u16(data, 2);
2409
2410 for (i = 0; i < limit; i++) {
2411 int32_t val = read_s32(data, 4 + (i * 4));
2412 memcpy(data + 4 + (i * 4), &val, sizeof(val));
2413 }
2414
2415 set_encodings(vs, (int32_t *)(data + 4), limit);
2416 break;
2417 case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
2418 if (len == 1)
2419 return 10;
2420
2421 framebuffer_update_request(vs,
2422 read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
2423 read_u16(data, 6), read_u16(data, 8));
2424 break;
2425 case VNC_MSG_CLIENT_KEY_EVENT:
2426 if (len == 1)
2427 return 8;
2428
2429 key_event(vs, read_u8(data, 1), read_u32(data, 4));
2430 break;
2431 case VNC_MSG_CLIENT_POINTER_EVENT:
2432 if (len == 1)
2433 return 6;
2434
2435 pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
2436 break;
2437 case VNC_MSG_CLIENT_CUT_TEXT:
2438 if (len == 1) {
2439 return 8;
2440 }
2441 if (len == 8) {
2442 uint32_t dlen = read_u32(data, 4);
2443 if (dlen > (1 << 20)) {
2444 error_report("vnc: client_cut_text msg payload has %u bytes"
2445 " which exceeds our limit of 1MB.", dlen);
2446 vnc_client_error(vs);
2447 break;
2448 }
2449 if (dlen > 0) {
2450 return 8 + dlen;
2451 }
2452 }
2453
2454 client_cut_text(vs, read_u32(data, 4), data + 8);
2455 break;
2456 case VNC_MSG_CLIENT_XVP:
2457 if (!(vs->features & VNC_FEATURE_XVP)) {
2458 error_report("vnc: xvp client message while disabled");
2459 vnc_client_error(vs);
2460 break;
2461 }
2462 if (len == 1) {
2463 return 4;
2464 }
2465 if (len == 4) {
2466 uint8_t version = read_u8(data, 2);
2467 uint8_t action = read_u8(data, 3);
2468
2469 if (version != 1) {
2470 error_report("vnc: xvp client message version %d != 1",
2471 version);
2472 vnc_client_error(vs);
2473 break;
2474 }
2475
2476 switch (action) {
2477 case VNC_XVP_ACTION_SHUTDOWN:
2478 qemu_system_powerdown_request();
2479 break;
2480 case VNC_XVP_ACTION_REBOOT:
2481 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2482 break;
2483 case VNC_XVP_ACTION_RESET:
2484 qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
2485 break;
2486 default:
2487 send_xvp_message(vs, VNC_XVP_CODE_FAIL);
2488 break;
2489 }
2490 }
2491 break;
2492 case VNC_MSG_CLIENT_QEMU:
2493 if (len == 1)
2494 return 2;
2495
2496 switch (read_u8(data, 1)) {
2497 case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
2498 if (len == 2)
2499 return 12;
2500
2501 ext_key_event(vs, read_u16(data, 2),
2502 read_u32(data, 4), read_u32(data, 8));
2503 break;
2504 case VNC_MSG_CLIENT_QEMU_AUDIO:
2505 if (len == 2)
2506 return 4;
2507
2508 switch (read_u16 (data, 2)) {
2509 case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
2510 trace_vnc_msg_client_audio_enable(vs, vs->ioc);
2511 audio_add(vs);
2512 break;
2513 case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
2514 trace_vnc_msg_client_audio_disable(vs, vs->ioc);
2515 audio_del(vs);
2516 break;
2517 case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
2518 if (len == 4)
2519 return 10;
2520 switch (read_u8(data, 4)) {
2521 case 0: vs->as.fmt = AUDIO_FORMAT_U8; break;
2522 case 1: vs->as.fmt = AUDIO_FORMAT_S8; break;
2523 case 2: vs->as.fmt = AUDIO_FORMAT_U16; break;
2524 case 3: vs->as.fmt = AUDIO_FORMAT_S16; break;
2525 case 4: vs->as.fmt = AUDIO_FORMAT_U32; break;
2526 case 5: vs->as.fmt = AUDIO_FORMAT_S32; break;
2527 default:
2528 VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
2529 vnc_client_error(vs);
2530 break;
2531 }
2532 vs->as.nchannels = read_u8(data, 5);
2533 if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
2534 VNC_DEBUG("Invalid audio channel count %d\n",
2535 read_u8(data, 5));
2536 vnc_client_error(vs);
2537 break;
2538 }
2539 freq = read_u32(data, 6);
2540
2541
2542
2543
2544 if (freq > 48000) {
2545 VNC_DEBUG("Invalid audio frequency %u > 48000", freq);
2546 vnc_client_error(vs);
2547 break;
2548 }
2549 vs->as.freq = freq;
2550 trace_vnc_msg_client_audio_format(
2551 vs, vs->ioc, vs->as.fmt, vs->as.nchannels, vs->as.freq);
2552 break;
2553 default:
2554 VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
2555 vnc_client_error(vs);
2556 break;
2557 }
2558 break;
2559
2560 default:
2561 VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
2562 vnc_client_error(vs);
2563 break;
2564 }
2565 break;
2566 case VNC_MSG_CLIENT_SET_DESKTOP_SIZE:
2567 {
2568 size_t size;
2569 uint8_t screens;
2570 int w, h;
2571
2572 if (len < 8) {
2573 return 8;
2574 }
2575
2576 screens = read_u8(data, 6);
2577 size = 8 + screens * 16;
2578 if (len < size) {
2579 return size;
2580 }
2581 w = read_u16(data, 2);
2582 h = read_u16(data, 4);
2583
2584 trace_vnc_msg_client_set_desktop_size(vs, vs->ioc, w, h, screens);
2585 if (dpy_ui_info_supported(vs->vd->dcl.con)) {
2586 QemuUIInfo info;
2587 memset(&info, 0, sizeof(info));
2588 info.width = w;
2589 info.height = h;
2590 dpy_set_ui_info(vs->vd->dcl.con, &info);
2591 vnc_desktop_resize_ext(vs, 4 );
2592 } else {
2593 vnc_desktop_resize_ext(vs, 3 );
2594 }
2595
2596 break;
2597 }
2598 default:
2599 VNC_DEBUG("Msg: %d\n", data[0]);
2600 vnc_client_error(vs);
2601 break;
2602 }
2603
2604 vnc_update_throttle_offset(vs);
2605 vnc_read_when(vs, protocol_client_msg, 1);
2606 return 0;
2607}
2608
2609static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
2610{
2611 char buf[1024];
2612 VncShareMode mode;
2613 int size;
2614
2615 mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
2616 switch (vs->vd->share_policy) {
2617 case VNC_SHARE_POLICY_IGNORE:
2618
2619
2620
2621
2622
2623
2624
2625 break;
2626 case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2637 VncState *client;
2638 QTAILQ_FOREACH(client, &vs->vd->clients, next) {
2639 if (vs == client) {
2640 continue;
2641 }
2642 if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
2643 client->share_mode != VNC_SHARE_MODE_SHARED) {
2644 continue;
2645 }
2646 vnc_disconnect_start(client);
2647 }
2648 }
2649 if (mode == VNC_SHARE_MODE_SHARED) {
2650 if (vs->vd->num_exclusive > 0) {
2651 vnc_disconnect_start(vs);
2652 return 0;
2653 }
2654 }
2655 break;
2656 case VNC_SHARE_POLICY_FORCE_SHARED:
2657
2658
2659
2660
2661
2662
2663
2664
2665 if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
2666 vnc_disconnect_start(vs);
2667 return 0;
2668 }
2669 break;
2670 }
2671 vnc_set_share_mode(vs, mode);
2672
2673 if (vs->vd->num_shared > vs->vd->connections_limit) {
2674 vnc_disconnect_start(vs);
2675 return 0;
2676 }
2677
2678 assert(pixman_image_get_width(vs->vd->server) < 65536 &&
2679 pixman_image_get_width(vs->vd->server) >= 0);
2680 assert(pixman_image_get_height(vs->vd->server) < 65536 &&
2681 pixman_image_get_height(vs->vd->server) >= 0);
2682 vs->client_width = pixman_image_get_width(vs->vd->server);
2683 vs->client_height = pixman_image_get_height(vs->vd->server);
2684 vnc_write_u16(vs, vs->client_width);
2685 vnc_write_u16(vs, vs->client_height);
2686
2687 pixel_format_message(vs);
2688
2689 if (qemu_name) {
2690 size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
2691 if (size > sizeof(buf)) {
2692 size = sizeof(buf);
2693 }
2694 } else {
2695 size = snprintf(buf, sizeof(buf), "QEMU");
2696 }
2697
2698 vnc_write_u32(vs, size);
2699 vnc_write(vs, buf, size);
2700 vnc_flush(vs);
2701
2702 vnc_client_cache_auth(vs);
2703 vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
2704
2705 vnc_read_when(vs, protocol_client_msg, 1);
2706
2707 return 0;
2708}
2709
2710void start_client_init(VncState *vs)
2711{
2712 vnc_read_when(vs, protocol_client_init, 1);
2713}
2714
2715static void authentication_failed(VncState *vs)
2716{
2717 vnc_write_u32(vs, 1);
2718 if (vs->minor >= 8) {
2719 static const char err[] = "Authentication failed";
2720 vnc_write_u32(vs, sizeof(err));
2721 vnc_write(vs, err, sizeof(err));
2722 }
2723 vnc_flush(vs);
2724 vnc_client_error(vs);
2725}
2726
2727static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
2728{
2729 unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
2730 size_t i, pwlen;
2731 unsigned char key[8];
2732 time_t now = time(NULL);
2733 QCryptoCipher *cipher = NULL;
2734 Error *err = NULL;
2735
2736 if (!vs->vd->password) {
2737 trace_vnc_auth_fail(vs, vs->auth, "password is not set", "");
2738 goto reject;
2739 }
2740 if (vs->vd->expires < now) {
2741 trace_vnc_auth_fail(vs, vs->auth, "password is expired", "");
2742 goto reject;
2743 }
2744
2745 memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
2746
2747
2748 pwlen = strlen(vs->vd->password);
2749 for (i=0; i<sizeof(key); i++)
2750 key[i] = i<pwlen ? vs->vd->password[i] : 0;
2751
2752 cipher = qcrypto_cipher_new(
2753 QCRYPTO_CIPHER_ALG_DES_RFB,
2754 QCRYPTO_CIPHER_MODE_ECB,
2755 key, G_N_ELEMENTS(key),
2756 &err);
2757 if (!cipher) {
2758 trace_vnc_auth_fail(vs, vs->auth, "cannot create cipher",
2759 error_get_pretty(err));
2760 error_free(err);
2761 goto reject;
2762 }
2763
2764 if (qcrypto_cipher_encrypt(cipher,
2765 vs->challenge,
2766 response,
2767 VNC_AUTH_CHALLENGE_SIZE,
2768 &err) < 0) {
2769 trace_vnc_auth_fail(vs, vs->auth, "cannot encrypt challenge response",
2770 error_get_pretty(err));
2771 error_free(err);
2772 goto reject;
2773 }
2774
2775
2776 if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
2777 trace_vnc_auth_fail(vs, vs->auth, "mis-matched challenge response", "");
2778 goto reject;
2779 } else {
2780 trace_vnc_auth_pass(vs, vs->auth);
2781 vnc_write_u32(vs, 0);
2782 vnc_flush(vs);
2783
2784 start_client_init(vs);
2785 }
2786
2787 qcrypto_cipher_free(cipher);
2788 return 0;
2789
2790reject:
2791 authentication_failed(vs);
2792 qcrypto_cipher_free(cipher);
2793 return 0;
2794}
2795
2796void start_auth_vnc(VncState *vs)
2797{
2798 Error *err = NULL;
2799
2800 if (qcrypto_random_bytes(vs->challenge, sizeof(vs->challenge), &err)) {
2801 trace_vnc_auth_fail(vs, vs->auth, "cannot get random bytes",
2802 error_get_pretty(err));
2803 error_free(err);
2804 authentication_failed(vs);
2805 return;
2806 }
2807
2808
2809 vnc_write(vs, vs->challenge, sizeof(vs->challenge));
2810 vnc_flush(vs);
2811
2812 vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
2813}
2814
2815
2816static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
2817{
2818
2819
2820 if (data[0] != vs->auth) {
2821 trace_vnc_auth_reject(vs, vs->auth, (int)data[0]);
2822 authentication_failed(vs);
2823 } else {
2824 trace_vnc_auth_start(vs, vs->auth);
2825 switch (vs->auth) {
2826 case VNC_AUTH_NONE:
2827 if (vs->minor >= 8) {
2828 vnc_write_u32(vs, 0);
2829 vnc_flush(vs);
2830 }
2831 trace_vnc_auth_pass(vs, vs->auth);
2832 start_client_init(vs);
2833 break;
2834
2835 case VNC_AUTH_VNC:
2836 start_auth_vnc(vs);
2837 break;
2838
2839 case VNC_AUTH_VENCRYPT:
2840 start_auth_vencrypt(vs);
2841 break;
2842
2843#ifdef CONFIG_VNC_SASL
2844 case VNC_AUTH_SASL:
2845 start_auth_sasl(vs);
2846 break;
2847#endif
2848
2849 default:
2850 trace_vnc_auth_fail(vs, vs->auth, "Unhandled auth method", "");
2851 authentication_failed(vs);
2852 }
2853 }
2854 return 0;
2855}
2856
2857static int protocol_version(VncState *vs, uint8_t *version, size_t len)
2858{
2859 char local[13];
2860
2861 memcpy(local, version, 12);
2862 local[12] = 0;
2863
2864 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
2865 VNC_DEBUG("Malformed protocol version %s\n", local);
2866 vnc_client_error(vs);
2867 return 0;
2868 }
2869 VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
2870 if (vs->major != 3 ||
2871 (vs->minor != 3 &&
2872 vs->minor != 4 &&
2873 vs->minor != 5 &&
2874 vs->minor != 7 &&
2875 vs->minor != 8)) {
2876 VNC_DEBUG("Unsupported client version\n");
2877 vnc_write_u32(vs, VNC_AUTH_INVALID);
2878 vnc_flush(vs);
2879 vnc_client_error(vs);
2880 return 0;
2881 }
2882
2883
2884
2885 if (vs->minor == 4 || vs->minor == 5)
2886 vs->minor = 3;
2887
2888 if (vs->minor == 3) {
2889 trace_vnc_auth_start(vs, vs->auth);
2890 if (vs->auth == VNC_AUTH_NONE) {
2891 vnc_write_u32(vs, vs->auth);
2892 vnc_flush(vs);
2893 trace_vnc_auth_pass(vs, vs->auth);
2894 start_client_init(vs);
2895 } else if (vs->auth == VNC_AUTH_VNC) {
2896 VNC_DEBUG("Tell client VNC auth\n");
2897 vnc_write_u32(vs, vs->auth);
2898 vnc_flush(vs);
2899 start_auth_vnc(vs);
2900 } else {
2901 trace_vnc_auth_fail(vs, vs->auth,
2902 "Unsupported auth method for v3.3", "");
2903 vnc_write_u32(vs, VNC_AUTH_INVALID);
2904 vnc_flush(vs);
2905 vnc_client_error(vs);
2906 }
2907 } else {
2908 vnc_write_u8(vs, 1);
2909 vnc_write_u8(vs, vs->auth);
2910 vnc_read_when(vs, protocol_client_auth, 1);
2911 vnc_flush(vs);
2912 }
2913
2914 return 0;
2915}
2916
2917static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
2918{
2919 struct VncSurface *vs = &vd->guest;
2920
2921 return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
2922}
2923
2924void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
2925{
2926 int i, j;
2927
2928 w = (x + w) / VNC_STAT_RECT;
2929 h = (y + h) / VNC_STAT_RECT;
2930 x /= VNC_STAT_RECT;
2931 y /= VNC_STAT_RECT;
2932
2933 for (j = y; j <= h; j++) {
2934 for (i = x; i <= w; i++) {
2935 vs->lossy_rect[j][i] = 1;
2936 }
2937 }
2938}
2939
2940static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
2941{
2942 VncState *vs;
2943 int sty = y / VNC_STAT_RECT;
2944 int stx = x / VNC_STAT_RECT;
2945 int has_dirty = 0;
2946
2947 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
2948 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
2949
2950 QTAILQ_FOREACH(vs, &vd->clients, next) {
2951 int j;
2952
2953
2954 if (vs->output.offset) {
2955 continue;
2956 }
2957
2958 if (!vs->lossy_rect[sty][stx]) {
2959 continue;
2960 }
2961
2962 vs->lossy_rect[sty][stx] = 0;
2963 for (j = 0; j < VNC_STAT_RECT; ++j) {
2964 bitmap_set(vs->dirty[y + j],
2965 x / VNC_DIRTY_PIXELS_PER_BIT,
2966 VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
2967 }
2968 has_dirty++;
2969 }
2970
2971 return has_dirty;
2972}
2973
2974static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
2975{
2976 int width = MIN(pixman_image_get_width(vd->guest.fb),
2977 pixman_image_get_width(vd->server));
2978 int height = MIN(pixman_image_get_height(vd->guest.fb),
2979 pixman_image_get_height(vd->server));
2980 int x, y;
2981 struct timeval res;
2982 int has_dirty = 0;
2983
2984 for (y = 0; y < height; y += VNC_STAT_RECT) {
2985 for (x = 0; x < width; x += VNC_STAT_RECT) {
2986 VncRectStat *rect = vnc_stat_rect(vd, x, y);
2987
2988 rect->updated = false;
2989 }
2990 }
2991
2992 qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
2993
2994 if (timercmp(&vd->guest.last_freq_check, &res, >)) {
2995 return has_dirty;
2996 }
2997 vd->guest.last_freq_check = *tv;
2998
2999 for (y = 0; y < height; y += VNC_STAT_RECT) {
3000 for (x = 0; x < width; x += VNC_STAT_RECT) {
3001 VncRectStat *rect= vnc_stat_rect(vd, x, y);
3002 int count = ARRAY_SIZE(rect->times);
3003 struct timeval min, max;
3004
3005 if (!timerisset(&rect->times[count - 1])) {
3006 continue ;
3007 }
3008
3009 max = rect->times[(rect->idx + count - 1) % count];
3010 qemu_timersub(tv, &max, &res);
3011
3012 if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
3013 rect->freq = 0;
3014 has_dirty += vnc_refresh_lossy_rect(vd, x, y);
3015 memset(rect->times, 0, sizeof (rect->times));
3016 continue ;
3017 }
3018
3019 min = rect->times[rect->idx];
3020 max = rect->times[(rect->idx + count - 1) % count];
3021 qemu_timersub(&max, &min, &res);
3022
3023 rect->freq = res.tv_sec + res.tv_usec / 1000000.;
3024 rect->freq /= count;
3025 rect->freq = 1. / rect->freq;
3026 }
3027 }
3028 return has_dirty;
3029}
3030
3031double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
3032{
3033 int i, j;
3034 double total = 0;
3035 int num = 0;
3036
3037 x = QEMU_ALIGN_DOWN(x, VNC_STAT_RECT);
3038 y = QEMU_ALIGN_DOWN(y, VNC_STAT_RECT);
3039
3040 for (j = y; j <= y + h; j += VNC_STAT_RECT) {
3041 for (i = x; i <= x + w; i += VNC_STAT_RECT) {
3042 total += vnc_stat_rect(vs->vd, i, j)->freq;
3043 num++;
3044 }
3045 }
3046
3047 if (num) {
3048 return total / num;
3049 } else {
3050 return 0;
3051 }
3052}
3053
3054static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
3055{
3056 VncRectStat *rect;
3057
3058 rect = vnc_stat_rect(vd, x, y);
3059 if (rect->updated) {
3060 return ;
3061 }
3062 rect->times[rect->idx] = *tv;
3063 rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
3064 rect->updated = true;
3065}
3066
3067static int vnc_refresh_server_surface(VncDisplay *vd)
3068{
3069 int width = MIN(pixman_image_get_width(vd->guest.fb),
3070 pixman_image_get_width(vd->server));
3071 int height = MIN(pixman_image_get_height(vd->guest.fb),
3072 pixman_image_get_height(vd->server));
3073 int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
3074 uint8_t *guest_row0 = NULL, *server_row0;
3075 VncState *vs;
3076 int has_dirty = 0;
3077 pixman_image_t *tmpbuf = NULL;
3078
3079 struct timeval tv = { 0, 0 };
3080
3081 if (!vd->non_adaptive) {
3082 gettimeofday(&tv, NULL);
3083 has_dirty = vnc_update_stats(vd, &tv);
3084 }
3085
3086
3087
3088
3089
3090
3091 server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
3092 server_stride = guest_stride = guest_ll =
3093 pixman_image_get_stride(vd->server);
3094 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
3095 server_stride);
3096 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3097 int width = pixman_image_get_width(vd->server);
3098 tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
3099 } else {
3100 int guest_bpp =
3101 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
3102 guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
3103 guest_stride = pixman_image_get_stride(vd->guest.fb);
3104 guest_ll = pixman_image_get_width(vd->guest.fb)
3105 * DIV_ROUND_UP(guest_bpp, 8);
3106 }
3107 line_bytes = MIN(server_stride, guest_ll);
3108
3109 for (;;) {
3110 int x;
3111 uint8_t *guest_ptr, *server_ptr;
3112 unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
3113 height * VNC_DIRTY_BPL(&vd->guest),
3114 y * VNC_DIRTY_BPL(&vd->guest));
3115 if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
3116
3117 break;
3118 }
3119 y = offset / VNC_DIRTY_BPL(&vd->guest);
3120 x = offset % VNC_DIRTY_BPL(&vd->guest);
3121
3122 server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
3123
3124 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
3125 qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
3126 guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
3127 } else {
3128 guest_ptr = guest_row0 + y * guest_stride;
3129 }
3130 guest_ptr += x * cmp_bytes;
3131
3132 for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
3133 x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
3134 int _cmp_bytes = cmp_bytes;
3135 if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
3136 continue;
3137 }
3138 if ((x + 1) * cmp_bytes > line_bytes) {
3139 _cmp_bytes = line_bytes - x * cmp_bytes;
3140 }
3141 assert(_cmp_bytes >= 0);
3142 if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
3143 continue;
3144 }
3145 memcpy(server_ptr, guest_ptr, _cmp_bytes);
3146 if (!vd->non_adaptive) {
3147 vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
3148 y, &tv);
3149 }
3150 QTAILQ_FOREACH(vs, &vd->clients, next) {
3151 set_bit(x, vs->dirty[y]);
3152 }
3153 has_dirty++;
3154 }
3155
3156 y++;
3157 }
3158 qemu_pixman_image_unref(tmpbuf);
3159 return has_dirty;
3160}
3161
3162static void vnc_refresh(DisplayChangeListener *dcl)
3163{
3164 VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
3165 VncState *vs, *vn;
3166 int has_dirty, rects = 0;
3167
3168 if (QTAILQ_EMPTY(&vd->clients)) {
3169 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
3170 return;
3171 }
3172
3173 graphic_hw_update(vd->dcl.con);
3174
3175 if (vnc_trylock_display(vd)) {
3176 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3177 return;
3178 }
3179
3180 has_dirty = vnc_refresh_server_surface(vd);
3181 vnc_unlock_display(vd);
3182
3183 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
3184 rects += vnc_update_client(vs, has_dirty);
3185
3186 }
3187
3188 if (has_dirty && rects) {
3189 vd->dcl.update_interval /= 2;
3190 if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
3191 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
3192 }
3193 } else {
3194 vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
3195 if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
3196 vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
3197 }
3198 }
3199}
3200
3201static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
3202 bool skipauth, bool websocket)
3203{
3204 VncState *vs = g_new0(VncState, 1);
3205 bool first_client = QTAILQ_EMPTY(&vd->clients);
3206 int i;
3207
3208 trace_vnc_client_connect(vs, sioc);
3209 vs->zrle = g_new0(VncZrle, 1);
3210 vs->tight = g_new0(VncTight, 1);
3211 vs->magic = VNC_MAGIC;
3212 vs->sioc = sioc;
3213 object_ref(OBJECT(vs->sioc));
3214 vs->ioc = QIO_CHANNEL(sioc);
3215 object_ref(OBJECT(vs->ioc));
3216 vs->vd = vd;
3217
3218 buffer_init(&vs->input, "vnc-input/%p", sioc);
3219 buffer_init(&vs->output, "vnc-output/%p", sioc);
3220 buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
3221
3222 buffer_init(&vs->tight->tight, "vnc-tight/%p", sioc);
3223 buffer_init(&vs->tight->zlib, "vnc-tight-zlib/%p", sioc);
3224 buffer_init(&vs->tight->gradient, "vnc-tight-gradient/%p", sioc);
3225#ifdef CONFIG_VNC_JPEG
3226 buffer_init(&vs->tight->jpeg, "vnc-tight-jpeg/%p", sioc);
3227#endif
3228#ifdef CONFIG_VNC_PNG
3229 buffer_init(&vs->tight->png, "vnc-tight-png/%p", sioc);
3230#endif
3231 buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
3232 buffer_init(&vs->zrle->zrle, "vnc-zrle/%p", sioc);
3233 buffer_init(&vs->zrle->fb, "vnc-zrle-fb/%p", sioc);
3234 buffer_init(&vs->zrle->zlib, "vnc-zrle-zlib/%p", sioc);
3235
3236 if (skipauth) {
3237 vs->auth = VNC_AUTH_NONE;
3238 vs->subauth = VNC_AUTH_INVALID;
3239 } else {
3240 if (websocket) {
3241 vs->auth = vd->ws_auth;
3242 vs->subauth = VNC_AUTH_INVALID;
3243 } else {
3244 vs->auth = vd->auth;
3245 vs->subauth = vd->subauth;
3246 }
3247 }
3248 VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
3249 sioc, websocket, vs->auth, vs->subauth);
3250
3251 vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
3252 for (i = 0; i < VNC_STAT_ROWS; ++i) {
3253 vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
3254 }
3255
3256 VNC_DEBUG("New client on socket %p\n", vs->sioc);
3257 update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
3258 qio_channel_set_blocking(vs->ioc, false, NULL);
3259 if (vs->ioc_tag) {
3260 g_source_remove(vs->ioc_tag);
3261 }
3262 if (websocket) {
3263 vs->websocket = 1;
3264 if (vd->tlscreds) {
3265 vs->ioc_tag = qio_channel_add_watch(
3266 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3267 vncws_tls_handshake_io, vs, NULL);
3268 } else {
3269 vs->ioc_tag = qio_channel_add_watch(
3270 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3271 vncws_handshake_io, vs, NULL);
3272 }
3273 } else {
3274 vs->ioc_tag = qio_channel_add_watch(
3275 vs->ioc, G_IO_IN | G_IO_HUP | G_IO_ERR,
3276 vnc_client_io, vs, NULL);
3277 }
3278
3279 vnc_client_cache_addr(vs);
3280 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
3281 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
3282
3283 vs->last_x = -1;
3284 vs->last_y = -1;
3285
3286 vs->as.freq = 44100;
3287 vs->as.nchannels = 2;
3288 vs->as.fmt = AUDIO_FORMAT_S16;
3289 vs->as.endianness = 0;
3290
3291 qemu_mutex_init(&vs->output_mutex);
3292 vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
3293
3294 QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
3295 if (first_client) {
3296 vnc_update_server_surface(vd);
3297 }
3298
3299 graphic_hw_update(vd->dcl.con);
3300
3301 if (!vs->websocket) {
3302 vnc_start_protocol(vs);
3303 }
3304
3305 if (vd->num_connecting > vd->connections_limit) {
3306 QTAILQ_FOREACH(vs, &vd->clients, next) {
3307 if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
3308 vnc_disconnect_start(vs);
3309 return;
3310 }
3311 }
3312 }
3313}
3314
3315void vnc_start_protocol(VncState *vs)
3316{
3317 vnc_write(vs, "RFB 003.008\n", 12);
3318 vnc_flush(vs);
3319 vnc_read_when(vs, protocol_version, 12);
3320
3321 vs->mouse_mode_notifier.notify = check_pointer_type_change;
3322 qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
3323}
3324
3325static void vnc_listen_io(QIONetListener *listener,
3326 QIOChannelSocket *cioc,
3327 void *opaque)
3328{
3329 VncDisplay *vd = opaque;
3330 bool isWebsock = listener == vd->wslistener;
3331
3332 qio_channel_set_name(QIO_CHANNEL(cioc),
3333 isWebsock ? "vnc-ws-server" : "vnc-server");
3334 qio_channel_set_delay(QIO_CHANNEL(cioc), false);
3335 vnc_connect(vd, cioc, false, isWebsock);
3336}
3337
3338static const DisplayChangeListenerOps dcl_ops = {
3339 .dpy_name = "vnc",
3340 .dpy_refresh = vnc_refresh,
3341 .dpy_gfx_update = vnc_dpy_update,
3342 .dpy_gfx_switch = vnc_dpy_switch,
3343 .dpy_gfx_check_format = qemu_pixman_check_format,
3344 .dpy_mouse_set = vnc_mouse_set,
3345 .dpy_cursor_define = vnc_dpy_cursor_define,
3346};
3347
3348void vnc_display_init(const char *id, Error **errp)
3349{
3350 VncDisplay *vd;
3351
3352 if (vnc_display_find(id) != NULL) {
3353 return;
3354 }
3355 vd = g_malloc0(sizeof(*vd));
3356
3357 vd->id = strdup(id);
3358 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next);
3359
3360 QTAILQ_INIT(&vd->clients);
3361 vd->expires = TIME_MAX;
3362
3363 if (keyboard_layout) {
3364 trace_vnc_key_map_init(keyboard_layout);
3365 vd->kbd_layout = init_keyboard_layout(name2keysym,
3366 keyboard_layout, errp);
3367 } else {
3368 vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us", errp);
3369 }
3370
3371 if (!vd->kbd_layout) {
3372 return;
3373 }
3374
3375 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
3376 vd->connections_limit = 32;
3377
3378 qemu_mutex_init(&vd->mutex);
3379 vnc_start_worker_thread();
3380
3381 vd->dcl.ops = &dcl_ops;
3382 register_displaychangelistener(&vd->dcl);
3383 vd->kbd = qkbd_state_init(vd->dcl.con);
3384}
3385
3386
3387static void vnc_display_close(VncDisplay *vd)
3388{
3389 if (!vd) {
3390 return;
3391 }
3392 vd->is_unix = false;
3393
3394 if (vd->listener) {
3395 qio_net_listener_disconnect(vd->listener);
3396 object_unref(OBJECT(vd->listener));
3397 }
3398 vd->listener = NULL;
3399
3400 if (vd->wslistener) {
3401 qio_net_listener_disconnect(vd->wslistener);
3402 object_unref(OBJECT(vd->wslistener));
3403 }
3404 vd->wslistener = NULL;
3405
3406 vd->auth = VNC_AUTH_INVALID;
3407 vd->subauth = VNC_AUTH_INVALID;
3408 if (vd->tlscreds) {
3409 object_unref(OBJECT(vd->tlscreds));
3410 vd->tlscreds = NULL;
3411 }
3412 if (vd->tlsauthz) {
3413 object_unparent(OBJECT(vd->tlsauthz));
3414 vd->tlsauthz = NULL;
3415 }
3416 g_free(vd->tlsauthzid);
3417 vd->tlsauthzid = NULL;
3418 if (vd->lock_key_sync) {
3419 qemu_remove_led_event_handler(vd->led);
3420 vd->led = NULL;
3421 }
3422#ifdef CONFIG_VNC_SASL
3423 if (vd->sasl.authz) {
3424 object_unparent(OBJECT(vd->sasl.authz));
3425 vd->sasl.authz = NULL;
3426 }
3427 g_free(vd->sasl.authzid);
3428 vd->sasl.authzid = NULL;
3429#endif
3430}
3431
3432int vnc_display_password(const char *id, const char *password)
3433{
3434 VncDisplay *vd = vnc_display_find(id);
3435
3436 if (!vd) {
3437 return -EINVAL;
3438 }
3439 if (vd->auth == VNC_AUTH_NONE) {
3440 error_printf_unless_qmp("If you want use passwords please enable "
3441 "password auth using '-vnc ${dpy},password'.\n");
3442 return -EINVAL;
3443 }
3444
3445 g_free(vd->password);
3446 vd->password = g_strdup(password);
3447
3448 return 0;
3449}
3450
3451int vnc_display_pw_expire(const char *id, time_t expires)
3452{
3453 VncDisplay *vd = vnc_display_find(id);
3454
3455 if (!vd) {
3456 return -EINVAL;
3457 }
3458
3459 vd->expires = expires;
3460 return 0;
3461}
3462
3463static void vnc_display_print_local_addr(VncDisplay *vd)
3464{
3465 SocketAddress *addr;
3466
3467 if (!vd->listener || !vd->listener->nsioc) {
3468 return;
3469 }
3470
3471 addr = qio_channel_socket_get_local_address(vd->listener->sioc[0], NULL);
3472 if (!addr) {
3473 return;
3474 }
3475
3476 if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
3477 qapi_free_SocketAddress(addr);
3478 return;
3479 }
3480 error_printf_unless_qmp("VNC server running on %s:%s\n",
3481 addr->u.inet.host,
3482 addr->u.inet.port);
3483 qapi_free_SocketAddress(addr);
3484}
3485
3486static QemuOptsList qemu_vnc_opts = {
3487 .name = "vnc",
3488 .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
3489 .implied_opt_name = "vnc",
3490 .desc = {
3491 {
3492 .name = "vnc",
3493 .type = QEMU_OPT_STRING,
3494 },{
3495 .name = "websocket",
3496 .type = QEMU_OPT_STRING,
3497 },{
3498 .name = "tls-creds",
3499 .type = QEMU_OPT_STRING,
3500 },{
3501 .name = "share",
3502 .type = QEMU_OPT_STRING,
3503 },{
3504 .name = "display",
3505 .type = QEMU_OPT_STRING,
3506 },{
3507 .name = "head",
3508 .type = QEMU_OPT_NUMBER,
3509 },{
3510 .name = "connections",
3511 .type = QEMU_OPT_NUMBER,
3512 },{
3513 .name = "to",
3514 .type = QEMU_OPT_NUMBER,
3515 },{
3516 .name = "ipv4",
3517 .type = QEMU_OPT_BOOL,
3518 },{
3519 .name = "ipv6",
3520 .type = QEMU_OPT_BOOL,
3521 },{
3522 .name = "password",
3523 .type = QEMU_OPT_BOOL,
3524 },{
3525 .name = "password-secret",
3526 .type = QEMU_OPT_STRING,
3527 },{
3528 .name = "reverse",
3529 .type = QEMU_OPT_BOOL,
3530 },{
3531 .name = "lock-key-sync",
3532 .type = QEMU_OPT_BOOL,
3533 },{
3534 .name = "key-delay-ms",
3535 .type = QEMU_OPT_NUMBER,
3536 },{
3537 .name = "sasl",
3538 .type = QEMU_OPT_BOOL,
3539 },{
3540 .name = "tls-authz",
3541 .type = QEMU_OPT_STRING,
3542 },{
3543 .name = "sasl-authz",
3544 .type = QEMU_OPT_STRING,
3545 },{
3546 .name = "lossy",
3547 .type = QEMU_OPT_BOOL,
3548 },{
3549 .name = "non-adaptive",
3550 .type = QEMU_OPT_BOOL,
3551 },{
3552 .name = "audiodev",
3553 .type = QEMU_OPT_STRING,
3554 },{
3555 .name = "power-control",
3556 .type = QEMU_OPT_BOOL,
3557 },
3558 { }
3559 },
3560};
3561
3562
3563static int
3564vnc_display_setup_auth(int *auth,
3565 int *subauth,
3566 QCryptoTLSCreds *tlscreds,
3567 bool password,
3568 bool sasl,
3569 bool websocket,
3570 Error **errp)
3571{
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619 if (websocket || !tlscreds) {
3620 if (password) {
3621 VNC_DEBUG("Initializing VNC server with password auth\n");
3622 *auth = VNC_AUTH_VNC;
3623 } else if (sasl) {
3624 VNC_DEBUG("Initializing VNC server with SASL auth\n");
3625 *auth = VNC_AUTH_SASL;
3626 } else {
3627 VNC_DEBUG("Initializing VNC server with no auth\n");
3628 *auth = VNC_AUTH_NONE;
3629 }
3630 *subauth = VNC_AUTH_INVALID;
3631 } else {
3632 bool is_x509 = object_dynamic_cast(OBJECT(tlscreds),
3633 TYPE_QCRYPTO_TLS_CREDS_X509) != NULL;
3634 bool is_anon = object_dynamic_cast(OBJECT(tlscreds),
3635 TYPE_QCRYPTO_TLS_CREDS_ANON) != NULL;
3636
3637 if (!is_x509 && !is_anon) {
3638 error_setg(errp,
3639 "Unsupported TLS cred type %s",
3640 object_get_typename(OBJECT(tlscreds)));
3641 return -1;
3642 }
3643 *auth = VNC_AUTH_VENCRYPT;
3644 if (password) {
3645 if (is_x509) {
3646 VNC_DEBUG("Initializing VNC server with x509 password auth\n");
3647 *subauth = VNC_AUTH_VENCRYPT_X509VNC;
3648 } else {
3649 VNC_DEBUG("Initializing VNC server with TLS password auth\n");
3650 *subauth = VNC_AUTH_VENCRYPT_TLSVNC;
3651 }
3652
3653 } else if (sasl) {
3654 if (is_x509) {
3655 VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
3656 *subauth = VNC_AUTH_VENCRYPT_X509SASL;
3657 } else {
3658 VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
3659 *subauth = VNC_AUTH_VENCRYPT_TLSSASL;
3660 }
3661 } else {
3662 if (is_x509) {
3663 VNC_DEBUG("Initializing VNC server with x509 no auth\n");
3664 *subauth = VNC_AUTH_VENCRYPT_X509NONE;
3665 } else {
3666 VNC_DEBUG("Initializing VNC server with TLS no auth\n");
3667 *subauth = VNC_AUTH_VENCRYPT_TLSNONE;
3668 }
3669 }
3670 }
3671 return 0;
3672}
3673
3674
3675static int vnc_display_get_address(const char *addrstr,
3676 bool websocket,
3677 bool reverse,
3678 int displaynum,
3679 int to,
3680 bool has_ipv4,
3681 bool has_ipv6,
3682 bool ipv4,
3683 bool ipv6,
3684 SocketAddress **retaddr,
3685 Error **errp)
3686{
3687 int ret = -1;
3688 SocketAddress *addr = NULL;
3689
3690 addr = g_new0(SocketAddress, 1);
3691
3692 if (strncmp(addrstr, "unix:", 5) == 0) {
3693 addr->type = SOCKET_ADDRESS_TYPE_UNIX;
3694 addr->u.q_unix.path = g_strdup(addrstr + 5);
3695
3696 if (websocket) {
3697 error_setg(errp, "UNIX sockets not supported with websock");
3698 goto cleanup;
3699 }
3700
3701 if (to) {
3702 error_setg(errp, "Port range not support with UNIX socket");
3703 goto cleanup;
3704 }
3705 ret = 0;
3706 } else {
3707 const char *port;
3708 size_t hostlen;
3709 unsigned long long baseport = 0;
3710 InetSocketAddress *inet;
3711
3712 port = strrchr(addrstr, ':');
3713 if (!port) {
3714 if (websocket) {
3715 hostlen = 0;
3716 port = addrstr;
3717 } else {
3718 error_setg(errp, "no vnc port specified");
3719 goto cleanup;
3720 }
3721 } else {
3722 hostlen = port - addrstr;
3723 port++;
3724 if (*port == '\0') {
3725 error_setg(errp, "vnc port cannot be empty");
3726 goto cleanup;
3727 }
3728 }
3729
3730 addr->type = SOCKET_ADDRESS_TYPE_INET;
3731 inet = &addr->u.inet;
3732 if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') {
3733 inet->host = g_strndup(addrstr + 1, hostlen - 2);
3734 } else {
3735 inet->host = g_strndup(addrstr, hostlen);
3736 }
3737
3738
3739 if (websocket) {
3740 if (g_str_equal(addrstr, "") ||
3741 g_str_equal(addrstr, "on")) {
3742 if (displaynum == -1) {
3743 error_setg(errp, "explicit websocket port is required");
3744 goto cleanup;
3745 }
3746 inet->port = g_strdup_printf(
3747 "%d", displaynum + 5700);
3748 if (to) {
3749 inet->has_to = true;
3750 inet->to = to + 5700;
3751 }
3752 } else {
3753 inet->port = g_strdup(port);
3754 }
3755 } else {
3756 int offset = reverse ? 0 : 5900;
3757 if (parse_uint_full(port, &baseport, 10) < 0) {
3758 error_setg(errp, "can't convert to a number: %s", port);
3759 goto cleanup;
3760 }
3761 if (baseport > 65535 ||
3762 baseport + offset > 65535) {
3763 error_setg(errp, "port %s out of range", port);
3764 goto cleanup;
3765 }
3766 inet->port = g_strdup_printf(
3767 "%d", (int)baseport + offset);
3768
3769 if (to) {
3770 inet->has_to = true;
3771 inet->to = to + offset;
3772 }
3773 }
3774
3775 inet->ipv4 = ipv4;
3776 inet->has_ipv4 = has_ipv4;
3777 inet->ipv6 = ipv6;
3778 inet->has_ipv6 = has_ipv6;
3779
3780 ret = baseport;
3781 }
3782
3783 *retaddr = addr;
3784
3785 cleanup:
3786 if (ret < 0) {
3787 qapi_free_SocketAddress(addr);
3788 }
3789 return ret;
3790}
3791
3792static void vnc_free_addresses(SocketAddress ***retsaddr,
3793 size_t *retnsaddr)
3794{
3795 size_t i;
3796
3797 for (i = 0; i < *retnsaddr; i++) {
3798 qapi_free_SocketAddress((*retsaddr)[i]);
3799 }
3800 g_free(*retsaddr);
3801
3802 *retsaddr = NULL;
3803 *retnsaddr = 0;
3804}
3805
3806static int vnc_display_get_addresses(QemuOpts *opts,
3807 bool reverse,
3808 SocketAddress ***retsaddr,
3809 size_t *retnsaddr,
3810 SocketAddress ***retwsaddr,
3811 size_t *retnwsaddr,
3812 Error **errp)
3813{
3814 SocketAddress *saddr = NULL;
3815 SocketAddress *wsaddr = NULL;
3816 QemuOptsIter addriter;
3817 const char *addr;
3818 int to = qemu_opt_get_number(opts, "to", 0);
3819 bool has_ipv4 = qemu_opt_get(opts, "ipv4");
3820 bool has_ipv6 = qemu_opt_get(opts, "ipv6");
3821 bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
3822 bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
3823 int displaynum = -1;
3824 int ret = -1;
3825
3826 *retsaddr = NULL;
3827 *retnsaddr = 0;
3828 *retwsaddr = NULL;
3829 *retnwsaddr = 0;
3830
3831 addr = qemu_opt_get(opts, "vnc");
3832 if (addr == NULL || g_str_equal(addr, "none")) {
3833 ret = 0;
3834 goto cleanup;
3835 }
3836 if (qemu_opt_get(opts, "websocket") &&
3837 !qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
3838 error_setg(errp,
3839 "SHA1 hash support is required for websockets");
3840 goto cleanup;
3841 }
3842
3843 qemu_opt_iter_init(&addriter, opts, "vnc");
3844 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3845 int rv;
3846 rv = vnc_display_get_address(addr, false, reverse, 0, to,
3847 has_ipv4, has_ipv6,
3848 ipv4, ipv6,
3849 &saddr, errp);
3850 if (rv < 0) {
3851 goto cleanup;
3852 }
3853
3854
3855
3856 if (displaynum == -1) {
3857 displaynum = rv;
3858 }
3859 *retsaddr = g_renew(SocketAddress *, *retsaddr, *retnsaddr + 1);
3860 (*retsaddr)[(*retnsaddr)++] = saddr;
3861 }
3862
3863
3864
3865 if (*retnsaddr > 1) {
3866 displaynum = -1;
3867 }
3868
3869 qemu_opt_iter_init(&addriter, opts, "websocket");
3870 while ((addr = qemu_opt_iter_next(&addriter)) != NULL) {
3871 if (vnc_display_get_address(addr, true, reverse, displaynum, to,
3872 has_ipv4, has_ipv6,
3873 ipv4, ipv6,
3874 &wsaddr, errp) < 0) {
3875 goto cleanup;
3876 }
3877
3878
3879
3880
3881
3882 if (*retnsaddr == 1 &&
3883 (*retsaddr)[0]->type == SOCKET_ADDRESS_TYPE_INET &&
3884 wsaddr->type == SOCKET_ADDRESS_TYPE_INET &&
3885 g_str_equal(wsaddr->u.inet.host, "") &&
3886 !g_str_equal((*retsaddr)[0]->u.inet.host, "")) {
3887 g_free(wsaddr->u.inet.host);
3888 wsaddr->u.inet.host = g_strdup((*retsaddr)[0]->u.inet.host);
3889 }
3890
3891 *retwsaddr = g_renew(SocketAddress *, *retwsaddr, *retnwsaddr + 1);
3892 (*retwsaddr)[(*retnwsaddr)++] = wsaddr;
3893 }
3894
3895 ret = 0;
3896 cleanup:
3897 if (ret < 0) {
3898 vnc_free_addresses(retsaddr, retnsaddr);
3899 vnc_free_addresses(retwsaddr, retnwsaddr);
3900 }
3901 return ret;
3902}
3903
3904static int vnc_display_connect(VncDisplay *vd,
3905 SocketAddress **saddr,
3906 size_t nsaddr,
3907 SocketAddress **wsaddr,
3908 size_t nwsaddr,
3909 Error **errp)
3910{
3911
3912 QIOChannelSocket *sioc = NULL;
3913 if (nwsaddr != 0) {
3914 error_setg(errp, "Cannot use websockets in reverse mode");
3915 return -1;
3916 }
3917 if (nsaddr != 1) {
3918 error_setg(errp, "Expected a single address in reverse mode");
3919 return -1;
3920 }
3921
3922 vd->is_unix = saddr[0]->type == SOCKET_ADDRESS_TYPE_UNIX;
3923 sioc = qio_channel_socket_new();
3924 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-reverse");
3925 if (qio_channel_socket_connect_sync(sioc, saddr[0], errp) < 0) {
3926 object_unref(OBJECT(sioc));
3927 return -1;
3928 }
3929 vnc_connect(vd, sioc, false, false);
3930 object_unref(OBJECT(sioc));
3931 return 0;
3932}
3933
3934
3935static int vnc_display_listen(VncDisplay *vd,
3936 SocketAddress **saddr,
3937 size_t nsaddr,
3938 SocketAddress **wsaddr,
3939 size_t nwsaddr,
3940 Error **errp)
3941{
3942 size_t i;
3943
3944 if (nsaddr) {
3945 vd->listener = qio_net_listener_new();
3946 qio_net_listener_set_name(vd->listener, "vnc-listen");
3947 for (i = 0; i < nsaddr; i++) {
3948 if (qio_net_listener_open_sync(vd->listener,
3949 saddr[i], 1,
3950 errp) < 0) {
3951 return -1;
3952 }
3953 }
3954
3955 qio_net_listener_set_client_func(vd->listener,
3956 vnc_listen_io, vd, NULL);
3957 }
3958
3959 if (nwsaddr) {
3960 vd->wslistener = qio_net_listener_new();
3961 qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
3962 for (i = 0; i < nwsaddr; i++) {
3963 if (qio_net_listener_open_sync(vd->wslistener,
3964 wsaddr[i], 1,
3965 errp) < 0) {
3966 return -1;
3967 }
3968 }
3969
3970 qio_net_listener_set_client_func(vd->wslistener,
3971 vnc_listen_io, vd, NULL);
3972 }
3973
3974 return 0;
3975}
3976
3977
3978void vnc_display_open(const char *id, Error **errp)
3979{
3980 VncDisplay *vd = vnc_display_find(id);
3981 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
3982 SocketAddress **saddr = NULL, **wsaddr = NULL;
3983 size_t nsaddr, nwsaddr;
3984 const char *share, *device_id;
3985 QemuConsole *con;
3986 bool password = false;
3987 bool reverse = false;
3988 const char *credid;
3989 bool sasl = false;
3990 const char *tlsauthz;
3991 const char *saslauthz;
3992 int lock_key_sync = 1;
3993 int key_delay_ms;
3994 const char *audiodev;
3995 const char *passwordSecret;
3996
3997 if (!vd) {
3998 error_setg(errp, "VNC display not active");
3999 return;
4000 }
4001 vnc_display_close(vd);
4002
4003 if (!opts) {
4004 return;
4005 }
4006
4007 reverse = qemu_opt_get_bool(opts, "reverse", false);
4008 if (vnc_display_get_addresses(opts, reverse, &saddr, &nsaddr,
4009 &wsaddr, &nwsaddr, errp) < 0) {
4010 goto fail;
4011 }
4012
4013
4014 passwordSecret = qemu_opt_get(opts, "password-secret");
4015 if (passwordSecret) {
4016 if (qemu_opt_get(opts, "password")) {
4017 error_setg(errp,
4018 "'password' flag is redundant with 'password-secret'");
4019 goto fail;
4020 }
4021 vd->password = qcrypto_secret_lookup_as_utf8(passwordSecret,
4022 errp);
4023 if (!vd->password) {
4024 goto fail;
4025 }
4026 password = true;
4027 } else {
4028 password = qemu_opt_get_bool(opts, "password", false);
4029 }
4030 if (password) {
4031 if (fips_get_state()) {
4032 error_setg(errp,
4033 "VNC password auth disabled due to FIPS mode, "
4034 "consider using the VeNCrypt or SASL authentication "
4035 "methods as an alternative");
4036 goto fail;
4037 }
4038 if (!qcrypto_cipher_supports(
4039 QCRYPTO_CIPHER_ALG_DES_RFB, QCRYPTO_CIPHER_MODE_ECB)) {
4040 error_setg(errp,
4041 "Cipher backend does not support DES RFB algorithm");
4042 goto fail;
4043 }
4044 }
4045
4046 lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
4047 key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 10);
4048 sasl = qemu_opt_get_bool(opts, "sasl", false);
4049#ifndef CONFIG_VNC_SASL
4050 if (sasl) {
4051 error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
4052 goto fail;
4053 }
4054#endif
4055 credid = qemu_opt_get(opts, "tls-creds");
4056 if (credid) {
4057 Object *creds;
4058 creds = object_resolve_path_component(
4059 object_get_objects_root(), credid);
4060 if (!creds) {
4061 error_setg(errp, "No TLS credentials with id '%s'",
4062 credid);
4063 goto fail;
4064 }
4065 vd->tlscreds = (QCryptoTLSCreds *)
4066 object_dynamic_cast(creds,
4067 TYPE_QCRYPTO_TLS_CREDS);
4068 if (!vd->tlscreds) {
4069 error_setg(errp, "Object with id '%s' is not TLS credentials",
4070 credid);
4071 goto fail;
4072 }
4073 object_ref(OBJECT(vd->tlscreds));
4074
4075 if (!qcrypto_tls_creds_check_endpoint(vd->tlscreds,
4076 QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
4077 errp)) {
4078 goto fail;
4079 }
4080 }
4081 tlsauthz = qemu_opt_get(opts, "tls-authz");
4082 if (tlsauthz && !vd->tlscreds) {
4083 error_setg(errp, "'tls-authz' provided but TLS is not enabled");
4084 goto fail;
4085 }
4086
4087 saslauthz = qemu_opt_get(opts, "sasl-authz");
4088 if (saslauthz && !sasl) {
4089 error_setg(errp, "'sasl-authz' provided but SASL auth is not enabled");
4090 goto fail;
4091 }
4092
4093 share = qemu_opt_get(opts, "share");
4094 if (share) {
4095 if (strcmp(share, "ignore") == 0) {
4096 vd->share_policy = VNC_SHARE_POLICY_IGNORE;
4097 } else if (strcmp(share, "allow-exclusive") == 0) {
4098 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4099 } else if (strcmp(share, "force-shared") == 0) {
4100 vd->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
4101 } else {
4102 error_setg(errp, "unknown vnc share= option");
4103 goto fail;
4104 }
4105 } else {
4106 vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
4107 }
4108 vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
4109
4110#ifdef CONFIG_VNC_JPEG
4111 vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
4112#endif
4113 vd->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
4114
4115
4116
4117 if (!vd->lossy) {
4118 vd->non_adaptive = true;
4119 }
4120
4121 vd->power_control = qemu_opt_get_bool(opts, "power-control", false);
4122
4123 if (tlsauthz) {
4124 vd->tlsauthzid = g_strdup(tlsauthz);
4125 }
4126#ifdef CONFIG_VNC_SASL
4127 if (sasl) {
4128 if (saslauthz) {
4129 vd->sasl.authzid = g_strdup(saslauthz);
4130 }
4131 }
4132#endif
4133
4134 if (vnc_display_setup_auth(&vd->auth, &vd->subauth,
4135 vd->tlscreds, password,
4136 sasl, false, errp) < 0) {
4137 goto fail;
4138 }
4139 trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth);
4140
4141 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth,
4142 vd->tlscreds, password,
4143 sasl, true, errp) < 0) {
4144 goto fail;
4145 }
4146 trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
4147
4148#ifdef CONFIG_VNC_SASL
4149 if (sasl) {
4150 int saslErr = sasl_server_init(NULL, "qemu");
4151
4152 if (saslErr != SASL_OK) {
4153 error_setg(errp, "Failed to initialize SASL auth: %s",
4154 sasl_errstring(saslErr, NULL, NULL));
4155 goto fail;
4156 }
4157 }
4158#endif
4159 vd->lock_key_sync = lock_key_sync;
4160 if (lock_key_sync) {
4161 vd->led = qemu_add_led_event_handler(kbd_leds, vd);
4162 }
4163 vd->ledstate = 0;
4164
4165 audiodev = qemu_opt_get(opts, "audiodev");
4166 if (audiodev) {
4167 vd->audio_state = audio_state_by_name(audiodev);
4168 if (!vd->audio_state) {
4169 error_setg(errp, "Audiodev '%s' not found", audiodev);
4170 goto fail;
4171 }
4172 }
4173
4174 device_id = qemu_opt_get(opts, "display");
4175 if (device_id) {
4176 int head = qemu_opt_get_number(opts, "head", 0);
4177 Error *err = NULL;
4178
4179 con = qemu_console_lookup_by_device_name(device_id, head, &err);
4180 if (err) {
4181 error_propagate(errp, err);
4182 goto fail;
4183 }
4184 } else {
4185 con = NULL;
4186 }
4187
4188 if (con != vd->dcl.con) {
4189 qkbd_state_free(vd->kbd);
4190 unregister_displaychangelistener(&vd->dcl);
4191 vd->dcl.con = con;
4192 register_displaychangelistener(&vd->dcl);
4193 vd->kbd = qkbd_state_init(vd->dcl.con);
4194 }
4195 qkbd_state_set_delay(vd->kbd, key_delay_ms);
4196
4197 if (saddr == NULL) {
4198 goto cleanup;
4199 }
4200
4201 if (reverse) {
4202 if (vnc_display_connect(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4203 goto fail;
4204 }
4205 } else {
4206 if (vnc_display_listen(vd, saddr, nsaddr, wsaddr, nwsaddr, errp) < 0) {
4207 goto fail;
4208 }
4209 }
4210
4211 if (qemu_opt_get(opts, "to")) {
4212 vnc_display_print_local_addr(vd);
4213 }
4214
4215 cleanup:
4216 vnc_free_addresses(&saddr, &nsaddr);
4217 vnc_free_addresses(&wsaddr, &nwsaddr);
4218 return;
4219
4220fail:
4221 vnc_display_close(vd);
4222 goto cleanup;
4223}
4224
4225void vnc_display_add_client(const char *id, int csock, bool skipauth)
4226{
4227 VncDisplay *vd = vnc_display_find(id);
4228 QIOChannelSocket *sioc;
4229
4230 if (!vd) {
4231 return;
4232 }
4233
4234 sioc = qio_channel_socket_new_fd(csock, NULL);
4235 if (sioc) {
4236 qio_channel_set_name(QIO_CHANNEL(sioc), "vnc-server");
4237 vnc_connect(vd, sioc, skipauth, false);
4238 object_unref(OBJECT(sioc));
4239 }
4240}
4241
4242static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
4243{
4244 int i = 2;
4245 char *id;
4246
4247 id = g_strdup("default");
4248 while (qemu_opts_find(olist, id)) {
4249 g_free(id);
4250 id = g_strdup_printf("vnc%d", i++);
4251 }
4252 qemu_opts_set_id(opts, id);
4253}
4254
4255void vnc_parse(const char *str)
4256{
4257 QemuOptsList *olist = qemu_find_opts("vnc");
4258 QemuOpts *opts = qemu_opts_parse_noisily(olist, str, !is_help_option(str));
4259 const char *id;
4260
4261 if (!opts) {
4262 exit(1);
4263 }
4264
4265 id = qemu_opts_id(opts);
4266 if (!id) {
4267
4268 vnc_auto_assign_id(olist, opts);
4269 }
4270}
4271
4272int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
4273{
4274 Error *local_err = NULL;
4275 char *id = (char *)qemu_opts_id(opts);
4276
4277 assert(id);
4278 vnc_display_init(id, &local_err);
4279 if (local_err) {
4280 error_propagate(errp, local_err);
4281 return -1;
4282 }
4283 vnc_display_open(id, &local_err);
4284 if (local_err != NULL) {
4285 error_propagate(errp, local_err);
4286 return -1;
4287 }
4288 return 0;
4289}
4290
4291static void vnc_register_config(void)
4292{
4293 qemu_add_opts(&qemu_vnc_opts);
4294}
4295opts_init(vnc_register_config);
4296