1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
5 * Copyright (c) 2015 Leon Dang
6 * Copyright 2020 Joyent, Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30 /*
31 * This file and its contents are supplied under the terms of the
32 * Common Development and Distribution License ("CDDL"), version 1.0.
33 * You may only use this file in accordance with the terms of version
34 * 1.0 of the CDDL.
35 *
36 * A full copy of the text of the CDDL should have accompanied this
37 * source. A copy of the CDDL is also available via the Internet at
38 * http://www.illumos.org/license/CDDL.
39 *
40 * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
41 */
42
43 /*
44 * References to the RFB protocol specification refer to:
45 * - [1] https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst
46 */
47
48 #include <err.h>
49 #include <errno.h>
50 #include <libidspace.h>
51 #include <netdb.h>
52 #include <pthread.h>
53 #include <pthread_np.h>
54 #include <signal.h>
55 #include <stdatomic.h>
56 #include <stdbool.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <unistd.h>
61 #include <zlib.h>
62 #include <machine/cpufunc.h>
63 #include <machine/specialreg.h>
64 #include <netinet/in.h>
65 #ifndef NO_OPENSSL
66 #include <openssl/des.h>
67 #endif
68 #include <sys/debug.h>
69 #include <sys/endian.h>
70 #include <sys/list.h>
71 #include <sys/socket.h>
72 #include <sys/types.h>
73 #ifndef WITHOUT_CAPSICUM
74 #include <sysexits.h>
75 #include <sys/capsicum.h>
76 #include <capsicum_helpers.h>
77 #endif
78
79 #include "bhyvegc.h"
80 #include "config.h"
81 #include "debug.h"
82 #include "console.h"
83 #include "rfb.h"
84 #include "rfb_impl.h"
85 #include "sockstream.h"
86
87 static uint_t rfb_debug = 0;
88 static list_t rfb_list;
89 static id_space_t *rfb_idspace;
90
91 static bool rfb_sse42;
92 static pthread_once_t rfb_once = PTHREAD_ONCE_INIT;
93
94 extern int raw_stdio;
95
96 static void rfb_send_extended_keyevent_update_msg(rfb_client_t *);
97
98 static void
rfb_printf(rfb_client_t * c,rfb_loglevel_t level,const char * fmt,...)99 rfb_printf(rfb_client_t *c, rfb_loglevel_t level, const char *fmt, ...)
100 {
101 FILE *fp = stdout;
102 va_list ap;
103
104 switch (level) {
105 case RFB_LOGDEBUG:
106 if (rfb_debug == 0)
107 return;
108 /* FALLTHROUGH */
109 case RFB_LOGERR:
110 fp = stderr;
111 /* FALLTHROUGH */
112 case RFB_LOGWARN:
113 if (c != NULL)
114 (void) fprintf(fp, "rfb%u: ", c->rc_instance);
115 else
116 (void) fprintf(fp, "rfb: ");
117 va_start(ap, fmt);
118 (void) vfprintf(fp, fmt, ap);
119 va_end(ap);
120 if (raw_stdio)
121 (void) fprintf(fp, "\r\n");
122 else
123 (void) fprintf(fp, "\n");
124 (void) fflush(fp);
125 }
126 }
127
128 static void
rfb_init_once(void)129 rfb_init_once(void)
130 {
131 uint_t cpu_registers[4], ecx;
132
133 do_cpuid(1, cpu_registers);
134 ecx = cpu_registers[2];
135 rfb_sse42 = (ecx & CPUID2_SSE42) != 0;
136
137 if (rfb_sse42)
138 rfb_printf(NULL, RFB_LOGDEBUG, "enabled fast crc32");
139 else
140 rfb_printf(NULL, RFB_LOGWARN, "no support for fast crc32");
141
142 if (get_config_bool_default("rfb.debug", false))
143 rfb_debug = 1;
144
145 list_create(&rfb_list, sizeof (rfb_server_t),
146 offsetof(rfb_server_t, rs_node));
147
148 rfb_idspace = id_space_create("rfb", 0, INT32_MAX);
149 }
150
151 static void
rfb_free_client(rfb_client_t * c)152 rfb_free_client(rfb_client_t *c)
153 {
154 free(c->rc_crc);
155 free(c->rc_crc_tmp);
156 free(c->rc_zbuf);
157 free(c->rc_gci.data);
158
159 if (c->rc_encodings & RFB_ENCODING_ZLIB)
160 (void) deflateEnd(&c->rc_zstream);
161
162 if (c->rc_fd != -1)
163 (void) close(c->rc_fd);
164
165 free(c);
166 }
167
168 /*
169 * Calculate CRC32 using SSE4.2; Intel or AMD Bulldozer+ CPUs only
170 */
171 static inline uint32_t
fast_crc32(void * buf,int len,uint32_t crcval)172 fast_crc32(void *buf, int len, uint32_t crcval)
173 {
174 uint32_t q = len / sizeof (uint32_t);
175 uint32_t *p = (uint32_t *)buf;
176
177 while (q--) {
178 /* BEGIN CSTYLED */
179 asm volatile (
180 /* crc32l %ecx,%esi */
181 ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
182 :"=S" (crcval)
183 :"0" (crcval), "c" (*p)
184 );
185 /* END CSTYLED */
186 p++;
187 }
188
189 return (crcval);
190 }
191
192 static void
rfb_send_client_status(rfb_client_t * c,uint32_t status,const char * msg)193 rfb_send_client_status(rfb_client_t *c, uint32_t status, const char *msg)
194 {
195 rfb_printf(c, RFB_LOGDEBUG, "sending client status %u (%s)",
196 status, msg ? msg : "NULL");
197
198 status = htonl(status);
199 (void) stream_write(c->rc_fd, &status, sizeof (status));
200
201 if (msg != NULL && status != 0 && c->rc_cver == RFB_CVER_3_8) {
202 char buf[4];
203
204 rfb_printf(c, RFB_LOGWARN, msg);
205
206 be32enc(buf, strlen((char *)msg));
207 (void) stream_write(c->rc_fd, buf, 4);
208 (void) stream_write(c->rc_fd, msg, strlen((char *)msg));
209 }
210 }
211
212 static bool
rfb_handshake_version(rfb_client_t * c)213 rfb_handshake_version(rfb_client_t *c)
214 {
215 unsigned char buf[RFB_VERSION_LEN];
216 ssize_t l;
217
218 rfb_printf(c, RFB_LOGDEBUG, "handshake version");
219
220 if (stream_write(c->rc_fd, RFB_VERSION, RFB_VERSION_LEN) !=
221 RFB_VERSION_LEN) {
222 rfb_printf(c, RFB_LOGWARN, "could not send server version.");
223 return (false);
224 }
225
226 l = stream_read(c->rc_fd, buf, sizeof (buf));
227 if (l <= 0) {
228 rfb_printf(c, RFB_LOGWARN, "client version not read");
229 return (false);
230 } else if (l != RFB_VERSION_LEN) {
231 rfb_printf(c, RFB_LOGWARN, "client sent short version - '%.*s'",
232 l, buf);
233 return (false);
234 }
235
236 rfb_printf(c, RFB_LOGDEBUG, "version handshake, client ver '%.*s'",
237 l - 1, buf);
238
239 if (strncmp(RFB_VERSION, (char *)buf, RFB_VERSION_LEN - 2) != 0) {
240 rfb_printf(c, RFB_LOGERR, "bad client version '%.*s'", l, buf);
241 return (false);
242 }
243
244 switch (buf[RFB_VERSION_LEN - 2]) {
245 case '8':
246 c->rc_cver = RFB_CVER_3_8;
247 break;
248 case '7':
249 c->rc_cver = RFB_CVER_3_7;
250 break;
251 case '5':
252 /*
253 * From the RFB specification[1], section 7.1.1:
254 * "version 3.5 was wrongly reported by some clients, but this
255 * should be interpreted by all servers as 3.3."
256 */
257 case '3':
258 c->rc_cver = RFB_CVER_3_3;
259 break;
260 default:
261 rfb_printf(c, RFB_LOGERR, "unsupported client version '%.*s'",
262 l - 1, buf);
263 return (false);
264 }
265
266 return (true);
267 }
268
269 static bool
rfb_handshake_auth(rfb_client_t * c)270 rfb_handshake_auth(rfb_client_t *c)
271 {
272 unsigned char buf[RFBP_SECURITY_VNC_AUTH_LEN];
273 int auth_type;
274
275 rfb_printf(c, RFB_LOGDEBUG, "handshake auth");
276
277 auth_type = RFBP_SECURITY_NONE;
278 #ifndef NO_OPENSSL
279 if (c->rc_s->rs_password != NULL)
280 auth_type = RFBP_SECURITY_VNC_AUTH;
281 #endif
282
283 switch (c->rc_cver) {
284 case RFB_CVER_3_3:
285 /*
286 * RFB specification[1] section 7.1.2:
287 * The server decides the security type and sends a single word.
288 */
289 be32enc(buf, auth_type);
290 (void) stream_write(c->rc_fd, buf, 4);
291
292 break;
293
294 case RFB_CVER_3_7:
295 case RFB_CVER_3_8:
296 /* Send list of supported types. */
297 buf[0] = 1; /* list length */
298 buf[1] = auth_type;
299 (void) stream_write(c->rc_fd, buf, 2);
300
301 /* Read agreed security type. */
302 if (stream_read(c->rc_fd, buf, 1) != 1) {
303 rfb_printf(c, RFB_LOGWARN,
304 "auth fail, no type from client");
305 return (false);
306 }
307
308 if (buf[0] != auth_type) {
309 rfb_send_client_status(c, 1,
310 "Auth failed: authentication type mismatch");
311 return (false);
312 }
313
314 break;
315 }
316
317 if (auth_type == RFBP_SECURITY_NONE) {
318 /*
319 * According to the RFB specification[1], section 7.2.1, for a
320 * security type of 'None', client versions 3.3 and 3.7 expect
321 * to move straight to the ClientInit phase, without the server
322 * sending a response. For version 3.8, a SecurityResult word
323 * needs to be sent indicating success.
324 */
325 switch (c->rc_cver) {
326 case RFB_CVER_3_3:
327 case RFB_CVER_3_7:
328 break;
329 case RFB_CVER_3_8:
330 rfb_send_client_status(c, 0, NULL);
331 break;
332 }
333 return (true);
334 }
335
336 /* Perform VNC authentication. */
337
338 #ifdef NO_OPENSSL
339 rfb_printf(c, RFB_LOGERR,
340 "Auth not supported, no OpenSSL in your system");
341 rfb_send_client_status(c, 1, "Auth failed.");
342 return (false);
343 #else
344 unsigned char challenge[RFBP_SECURITY_VNC_AUTH_LEN];
345 unsigned char keystr[RFBP_SECURITY_VNC_PASSWD_LEN];
346 unsigned char crypt_expected[RFBP_SECURITY_VNC_AUTH_LEN];
347 DES_key_schedule ks;
348
349 /*
350 * The client encrypts the challenge with DES, using a password
351 * supplied by the user as the key.
352 * To form the key, the password is truncated to eight characters, or
353 * padded with null bytes on the right.
354 * The client then sends the resulting 16-bytes response.
355 */
356 (void) strncpy((char *)keystr, c->rc_s->rs_password,
357 RFBP_SECURITY_VNC_PASSWD_LEN);
358
359 /*
360 * VNC clients encrypt the challenge with all the bit fields in each
361 * byte of the password mirrored.
362 * Here we flip each byte of the keystr.
363 */
364 for (uint_t i = 0; i < RFBP_SECURITY_VNC_PASSWD_LEN; i++) {
365 keystr[i] = (keystr[i] & 0xf0) >> 4 | (keystr[i] & 0x0f) << 4;
366 keystr[i] = (keystr[i] & 0xcc) >> 2 | (keystr[i] & 0x33) << 2;
367 keystr[i] = (keystr[i] & 0xaa) >> 1 | (keystr[i] & 0x55) << 1;
368 }
369
370 /* Initialize a 16-byte random challenge. */
371 arc4random_buf(challenge, sizeof (challenge));
372
373 /* Send the challenge to the client. */
374 if (stream_write(c->rc_fd, challenge, RFBP_SECURITY_VNC_AUTH_LEN)
375 != RFBP_SECURITY_VNC_AUTH_LEN) {
376 rfb_printf(c, RFB_LOGERR,
377 "failed to send challenge to client");
378 return (false);
379 }
380
381 /* Receive the 16-byte challenge response. */
382 if (stream_read(c->rc_fd, buf, RFBP_SECURITY_VNC_AUTH_LEN)
383 != RFBP_SECURITY_VNC_AUTH_LEN) {
384 rfb_send_client_status(c, 1, "Challenge response read failed");
385 return (false);
386 }
387
388 memcpy(crypt_expected, challenge, RFBP_SECURITY_VNC_AUTH_LEN);
389
390 /* Encrypt the Challenge with DES. */
391 DES_set_key_unchecked((const_DES_cblock *)keystr, &ks);
392 DES_ecb_encrypt((const_DES_cblock *)challenge,
393 (const_DES_cblock *)crypt_expected, &ks, DES_ENCRYPT);
394 DES_ecb_encrypt(
395 (const_DES_cblock *)(challenge + RFBP_SECURITY_VNC_PASSWD_LEN),
396 (const_DES_cblock *)(crypt_expected + RFBP_SECURITY_VNC_PASSWD_LEN),
397 &ks, DES_ENCRYPT);
398
399 if (memcmp(crypt_expected, buf, RFBP_SECURITY_VNC_AUTH_LEN) != 0) {
400 rfb_send_client_status(c, 1, "Auth failed: Invalid password.");
401 return (false);
402 }
403
404 rfb_printf(c, RFB_LOGDEBUG, "authentication succeeded");
405 rfb_send_client_status(c, 0, NULL);
406 #endif
407
408 return (true);
409 }
410
411 static bool
rfb_handshake_init_message(rfb_client_t * c)412 rfb_handshake_init_message(rfb_client_t *c)
413 {
414 struct bhyvegc_image *gci;
415 char buf[1];
416 char *name;
417
418 rfb_printf(c, RFB_LOGDEBUG, "handshake server init");
419
420 /* Read the client init message. */
421 if (stream_read(c->rc_fd, buf, 1) != 1) {
422 rfb_printf(c, RFB_LOGWARN, "client did not send init");
423 return (false);
424 }
425
426 if (buf[0] == 0) {
427 rfb_client_t *oc;
428
429 rfb_printf(c, RFB_LOGDEBUG,
430 "client requested exclusive access");
431
432 pthread_mutex_lock(&c->rc_s->rs_clientlock);
433 c->rc_s->rs_exclusive = true;
434 /* Disconnect all other clients. */
435 for (oc = list_head(&c->rc_s->rs_clients); oc != NULL;
436 oc = list_next(&c->rc_s->rs_clients, oc)) {
437 if (oc != c)
438 oc->rc_closing = true;
439 }
440 pthread_mutex_unlock(&c->rc_s->rs_clientlock);
441 } else {
442 rfb_printf(c, RFB_LOGDEBUG, "client requested shared access");
443
444 pthread_mutex_lock(&c->rc_s->rs_clientlock);
445 if (c->rc_s->rs_exclusive) {
446 rfb_printf(c, RFB_LOGWARN,
447 "deny due to existing exclusive session");
448 pthread_mutex_unlock(&c->rc_s->rs_clientlock);
449 return (false);
450 }
451 pthread_mutex_unlock(&c->rc_s->rs_clientlock);
452 }
453
454 gci = console_get_image();
455
456 c->rc_sinfo.rsi_width = htons(gci->width);
457 c->rc_sinfo.rsi_height = htons(gci->height);
458 c->rc_width = gci->width;
459 c->rc_height = gci->height;
460
461 if (c->rc_s->rs_name != NULL)
462 name = (char *)c->rc_s->rs_name;
463 else
464 name = "bhyve";
465
466 c->rc_sinfo.rsi_namelen = htonl(strlen(name));
467 (void) stream_write(c->rc_fd, &c->rc_sinfo, sizeof (c->rc_sinfo));
468 (void) stream_write(c->rc_fd, name, strlen(name));
469
470 return (true);
471 }
472
473 static bool
rfb_handshake(rfb_client_t * c)474 rfb_handshake(rfb_client_t *c)
475 {
476 if (!rfb_handshake_version(c))
477 return (false);
478
479 if (!rfb_handshake_auth(c))
480 return (false);
481
482 if (!rfb_handshake_init_message(c))
483 return (false);
484
485 return (true);
486 }
487
488 static void
rfb_print_pixfmt(rfb_client_t * c,rfb_pixfmt_t * px,rfb_loglevel_t level)489 rfb_print_pixfmt(rfb_client_t *c, rfb_pixfmt_t *px, rfb_loglevel_t level)
490 {
491 rfb_printf(c, level, "%20s: %u", "bpp", px->rp_bpp);
492 rfb_printf(c, level, "%20s: %u", "depth", px->rp_depth);
493 rfb_printf(c, level, "%20s: %u", "bigendian", px->rp_bigendian);
494 rfb_printf(c, level, "%20s: %u", "truecolour", px->rp_truecolour);
495 rfb_printf(c, level, "%20s: %u", "r_max", ntohs(px->rp_r_max));
496 rfb_printf(c, level, "%20s: %u", "g_max", ntohs(px->rp_g_max));
497 rfb_printf(c, level, "%20s: %u", "b_max", ntohs(px->rp_b_max));
498 rfb_printf(c, level, "%20s: %u", "r_shift", px->rp_r_shift);
499 rfb_printf(c, level, "%20s: %u", "g_shift", px->rp_g_shift);
500 rfb_printf(c, level, "%20s: %u", "b_shift", px->rp_b_shift);
501 }
502
503 static bool
rfb_recv_set_pixel_format(rfb_client_t * c)504 rfb_recv_set_pixel_format(rfb_client_t *c)
505 {
506 rfb_cs_pixfmt_msg_t msg;
507 rfb_pixfmt_t *newpx = &msg.rp_pixfmt;
508 rfb_pixfmt_t *oldpx = &c->rc_sinfo.rsi_pixfmt;
509 rfb_pixfmt_t *spx = &c->rc_s->rs_pixfmt;
510
511 rfb_printf(c, RFB_LOGDEBUG, "received pixel format");
512
513 if (stream_read(c->rc_fd, &msg, sizeof (msg)) != sizeof (msg))
514 return (false);
515
516 /*
517 * The client has sent its desired pixel format. The protocol does not
518 * have a mechanism to reject this, we are supposed to just start using
519 * the requested format from the next update.
520 *
521 * At present, we can only support alternative rgb-shift values and
522 * will accept (and ignore) a new depth value.
523 */
524
525 if (oldpx->rp_bpp != newpx->rp_bpp ||
526 oldpx->rp_bigendian != newpx->rp_bigendian ||
527 oldpx->rp_truecolour != newpx->rp_truecolour ||
528 oldpx->rp_r_max != newpx->rp_r_max ||
529 oldpx->rp_g_max != newpx->rp_g_max ||
530 oldpx->rp_b_max != newpx->rp_b_max) {
531 rfb_printf(c, RFB_LOGWARN, "unsupported pixfmt from client");
532 rfb_print_pixfmt(c, newpx, RFB_LOGWARN);
533 return (false);
534 }
535
536 rfb_print_pixfmt(c, newpx, RFB_LOGDEBUG);
537
538 /* Check if the new shifts match the server's native values. */
539 if (newpx->rp_r_shift != spx->rp_r_shift ||
540 newpx->rp_g_shift != spx->rp_g_shift ||
541 newpx->rp_b_shift != spx->rp_b_shift) {
542 c->rc_custom_pixfmt = true;
543 rfb_printf(c, RFB_LOGDEBUG, "Using custom pixfmt");
544 } else {
545 c->rc_custom_pixfmt = false;
546 rfb_printf(c, RFB_LOGDEBUG, "Using native pixfmt");
547 }
548
549 c->rc_sinfo.rsi_pixfmt = msg.rp_pixfmt;
550 c->rc_crc_reset = true;
551
552 return (true);
553 }
554
555 static bool
rfb_recv_set_encodings(rfb_client_t * c)556 rfb_recv_set_encodings(rfb_client_t *c)
557 {
558 rfb_cs_encodings_msg_t msg;
559
560 rfb_printf(c, RFB_LOGDEBUG, "received encodings");
561
562 if (stream_read(c->rc_fd, &msg, sizeof (msg)) != sizeof (msg))
563 return (false);
564
565 msg.re_numencs = htons(msg.re_numencs);
566
567 rfb_printf(c, RFB_LOGDEBUG, "%d values", msg.re_numencs);
568
569 for (uint_t i = 0; i < msg.re_numencs; i++) {
570 uint32_t enc;
571
572 if (stream_read(c->rc_fd, &enc, sizeof (enc)) != sizeof (enc))
573 return (false);
574
575 enc = htonl(enc);
576
577 switch (enc) {
578 case RFBP_ENCODING_RAW:
579 rfb_printf(c, RFB_LOGDEBUG,
580 "client supports raw encoding");
581 c->rc_encodings |= RFB_ENCODING_RAW;
582 break;
583 case RFBP_ENCODING_ZLIB:
584 rfb_printf(c, RFB_LOGDEBUG,
585 "client supports zlib encoding");
586 if (!(c->rc_encodings & RFB_ENCODING_ZLIB)) {
587 if (deflateInit(&c->rc_zstream, Z_BEST_SPEED)
588 != Z_OK) {
589 return (false);
590 }
591 c->rc_encodings |= RFB_ENCODING_ZLIB;
592 }
593 break;
594 case RFBP_ENCODING_RESIZE:
595 rfb_printf(c, RFB_LOGDEBUG, "client supports resize");
596 c->rc_encodings |= RFB_ENCODING_RESIZE;
597 break;
598 case RFBP_ENCODING_EXT_KEVENT:
599 rfb_printf(c, RFB_LOGDEBUG,
600 "client supports ext key event");
601 c->rc_encodings |= RFB_ENCODING_EXT_KEVENT;
602 break;
603 case RFBP_ENCODING_DESKTOP_NAME:
604 rfb_printf(c, RFB_LOGDEBUG,
605 "client supports desktop name");
606 c->rc_encodings |= RFB_ENCODING_DESKTOP_NAME;
607 break;
608 default:
609 rfb_printf(c, RFB_LOGDEBUG,
610 "client supports encoding %d", (int32_t)enc);
611 }
612 }
613
614 return (true);
615 }
616
617 static bool
rfb_recv_update(rfb_client_t * c)618 rfb_recv_update(rfb_client_t *c)
619 {
620 rfb_cs_update_msg_t msg;
621
622 if (stream_read(c->rc_fd, &msg, sizeof (msg)) != sizeof (msg))
623 return (false);
624
625 if (!c->rc_keyevent_sent &&
626 (c->rc_encodings & RFB_ENCODING_EXT_KEVENT)) {
627 /*
628 * Take this opportunity to tell the client that we
629 * accept QEMU Extended Key Event Pseudo-encoding.
630 */
631 c->rc_keyevent_sent = true;
632 rfb_send_extended_keyevent_update_msg(c);
633 }
634
635 c->rc_pending = true;
636 if (msg.rum_incremental == 0) {
637 rfb_printf(c, RFB_LOGDEBUG,
638 "client requested full screen update");
639 c->rc_send_fullscreen = true;
640 }
641
642 return (true);
643 }
644
645 static bool
rfb_recv_key_event(rfb_client_t * c)646 rfb_recv_key_event(rfb_client_t *c)
647 {
648 rfb_cs_key_event_msg_t msg;
649
650 if (stream_read(c->rc_fd, &msg, sizeof (msg)) != sizeof (msg))
651 return (false);
652
653 msg.rke_sym = htonl(msg.rke_sym);
654
655 rfb_printf(c, RFB_LOGDEBUG, "received key %s %x",
656 msg.rke_down == 0 ? "up" : "down", msg.rke_sym);
657
658 console_key_event(msg.rke_down, msg.rke_sym, htonl(0));
659 c->rc_input_detected = true;
660
661 return (true);
662 }
663
664 static bool
rfb_recv_pointer_event(rfb_client_t * c)665 rfb_recv_pointer_event(rfb_client_t *c)
666 {
667 rfb_cs_pointer_event_msg_t msg;
668
669 if (stream_read(c->rc_fd, &msg, sizeof (msg)) != sizeof (msg))
670 return (false);
671
672 msg.rpe_x = htons(msg.rpe_x);
673 msg.rpe_y = htons(msg.rpe_y);
674
675 if (rfb_debug > 1) {
676 rfb_printf(c, RFB_LOGDEBUG, "received pointer event @ %dx%d",
677 msg.rpe_x, msg.rpe_y);
678 }
679
680 console_ptr_event(msg.rpe_button, msg.rpe_x, msg.rpe_y);
681 c->rc_input_detected = true;
682
683 return (true);
684 }
685
686 static bool
rfb_recv_cut_text(rfb_client_t * c)687 rfb_recv_cut_text(rfb_client_t *c)
688 {
689 rfb_cs_cut_text_msg_t msg;
690 unsigned char buf[32];
691
692 rfb_printf(c, RFB_LOGDEBUG, "received cut text event");
693
694 if (stream_read(c->rc_fd, &msg, sizeof (msg)) != sizeof (msg))
695 return (false);
696
697 msg.rct_length = htonl(msg.rct_length);
698 rfb_printf(c, RFB_LOGDEBUG, "%u bytes in buffer", msg.rct_length);
699 /* Consume the buffer */
700 while (msg.rct_length > 0) {
701 ssize_t l;
702
703 l = stream_read(c->rc_fd, buf,
704 MIN(sizeof (buf), msg.rct_length));
705 if (l <= 0)
706 return (false);
707 msg.rct_length -= l;
708 }
709
710 return (true);
711 }
712
713 static bool
rfb_recv_qemu(rfb_client_t * c)714 rfb_recv_qemu(rfb_client_t *c)
715 {
716 rfb_cs_qemu_msg_t msg;
717
718 rfb_printf(c, RFB_LOGDEBUG, "received QEMU event");
719
720 if (stream_read(c->rc_fd, &msg, sizeof (msg)) != sizeof (msg))
721 return (false);
722
723 switch (msg.rq_subtype) {
724 case RFBP_CS_QEMU_KEVENT: {
725 rfb_cs_qemu_extended_key_msg_t keymsg;
726
727 if (stream_read(c->rc_fd, &keymsg, sizeof (keymsg)) !=
728 sizeof (keymsg)) {
729 return (false);
730 }
731
732 keymsg.rqek_sym = htonl(keymsg.rqek_sym);
733 keymsg.rqek_code = htonl(keymsg.rqek_code);
734
735 rfb_printf(c, RFB_LOGDEBUG, "QEMU key %s %x / %x",
736 keymsg.rqek_down == 0 ? "up" : "down",
737 keymsg.rqek_sym, keymsg.rqek_code);
738
739 console_key_event((int)keymsg.rqek_down, keymsg.rqek_sym,
740 keymsg.rqek_code);
741 c->rc_input_detected = true;
742 break;
743 }
744 default:
745 rfb_printf(c, RFB_LOGWARN, "Unknown QEMU event subtype: %d\n",
746 msg.rq_subtype);
747 return (false);
748 }
749
750 return (true);
751 }
752
753 static bool
rfb_send_update_header(rfb_client_t * c,int numrects)754 rfb_send_update_header(rfb_client_t *c, int numrects)
755 {
756 rfb_server_update_msg_t msg;
757
758 msg.rss_type = RFBP_SC_UPDATE;
759 msg.rss_pad = 0;
760 msg.rss_numrects = htons(numrects);
761
762 return (stream_write(c->rc_fd, &msg, sizeof (msg)) == sizeof (msg));
763 }
764
765 static void
rfb_send_resize_update_msg(rfb_client_t * c)766 rfb_send_resize_update_msg(rfb_client_t *c)
767 {
768 rfb_rect_hdr_t rect;
769
770 rfb_printf(c, RFB_LOGDEBUG, "sending screen resize %dx%d",
771 c->rc_width, c->rc_height);
772
773 (void) rfb_send_update_header(c, 1);
774
775 rect.rr_x = htons(0);
776 rect.rr_y = htons(0);
777 rect.rr_width = htons(c->rc_width);
778 rect.rr_height = htons(c->rc_height);
779 rect.rr_encoding = htonl(RFBP_ENCODING_RESIZE);
780
781 (void) stream_write(c->rc_fd, &rect, sizeof (rect));
782 }
783
784 static void
rfb_send_extended_keyevent_update_msg(rfb_client_t * c)785 rfb_send_extended_keyevent_update_msg(rfb_client_t *c)
786 {
787 rfb_rect_hdr_t rect;
788
789 rfb_printf(c, RFB_LOGDEBUG, "sending extended keyevent update message");
790
791 (void) rfb_send_update_header(c, 1);
792
793 rect.rr_x = htons(0);
794 rect.rr_y = htons(0);
795 rect.rr_width = htons(c->rc_width);
796 rect.rr_height = htons(c->rc_height);
797 rect.rr_encoding = htonl(RFBP_ENCODING_EXT_KEVENT);
798
799 (void) stream_write(c->rc_fd, &rect, sizeof (rect));
800 }
801
802 static void
translate_pixels(rfb_client_t * c,struct bhyvegc_image * gci,int x1,int y1,int x2,int y2)803 translate_pixels(rfb_client_t *c, struct bhyvegc_image *gci,
804 int x1, int y1, int x2, int y2)
805 {
806 rfb_pixfmt_t *px = &c->rc_sinfo.rsi_pixfmt;
807 rfb_pixfmt_t *spx = &c->rc_s->rs_pixfmt;
808 int w, h;
809
810 w = gci->width;
811 h = gci->height;
812 VERIFY3S(gci->width, ==, c->rc_gci.width);
813 VERIFY3S(gci->height, ==, c->rc_gci.height);
814
815 for (uint_t y = y1; y < h && y < y2; y++) {
816 for (uint_t x = x1; x < w && x < x2; x++) {
817 uint32_t p;
818
819 p = gci->data[y * w + x];
820 c->rc_gci.data[y * w + x] =
821 0xff000000 |
822 ((p >> spx->rp_r_shift) & 0xff) << px->rp_r_shift |
823 ((p >> spx->rp_g_shift) & 0xff) << px->rp_g_shift |
824 ((p >> spx->rp_b_shift) & 0xff) << px->rp_b_shift;
825 }
826 }
827 }
828
829 static bool
rfb_send_rect(rfb_client_t * c,struct bhyvegc_image * gci,int x,int y,int w,int h)830 rfb_send_rect(rfb_client_t *c, struct bhyvegc_image *gci,
831 int x, int y, int w, int h)
832 {
833 rfb_rect_hdr_t rect;
834 unsigned long zlen;
835 ssize_t nwrite, total;
836 int err;
837 uint32_t *p;
838 uint8_t *zbufp;
839
840 if (rfb_debug > 1) {
841 rfb_printf(c, RFB_LOGDEBUG, "send rect %dx%d %dx%d",
842 x, y, w, h);
843 }
844
845 /* Rectangle header. */
846 rect.rr_x = htons(x);
847 rect.rr_y = htons(y);
848 rect.rr_width = htons(w);
849 rect.rr_height = htons(h);
850
851 uint32_t *data = gci->data;
852 if (c->rc_custom_pixfmt) {
853 translate_pixels(c, gci, x, y, x + w, y + h);
854 data = c->rc_gci.data;
855 }
856
857 h = y + h;
858 w *= sizeof (uint32_t);
859
860 if (c->rc_encodings & RFB_ENCODING_ZLIB) {
861 zbufp = c->rc_zbuf;
862 c->rc_zstream.total_in = 0;
863 c->rc_zstream.total_out = 0;
864 for (p = &data[y * gci->width + x]; y < h; y++) {
865 c->rc_zstream.next_in = (Bytef *)p;
866 c->rc_zstream.avail_in = w;
867 c->rc_zstream.next_out = (Bytef *)zbufp;
868 c->rc_zstream.avail_out = RFB_ZLIB_BUFSZ + 16 -
869 c->rc_zstream.total_out;
870 c->rc_zstream.data_type = Z_BINARY;
871
872 /* Compress with zlib. */
873 err = deflate(&c->rc_zstream, Z_SYNC_FLUSH);
874 if (err != Z_OK) {
875 rfb_printf(c, RFB_LOGWARN,
876 "zlib[rect] deflate err: %d", err);
877 goto doraw;
878 }
879 zbufp = c->rc_zbuf + c->rc_zstream.total_out;
880 p += gci->width;
881 }
882 rect.rr_encoding = htonl(RFBP_ENCODING_ZLIB);
883 nwrite = stream_write(c->rc_fd, &rect, sizeof (rect));
884 if (nwrite <= 0)
885 return (false);
886
887 zlen = htonl(c->rc_zstream.total_out);
888 nwrite = stream_write(c->rc_fd, &zlen, sizeof (uint32_t));
889 if (nwrite <= 0)
890 return (false);
891 return (stream_write(c->rc_fd, c->rc_zbuf,
892 c->rc_zstream.total_out) == c->rc_zstream.total_out);
893 }
894
895 doraw:
896
897 total = 0;
898 zbufp = c->rc_zbuf;
899 for (p = &data[y * gci->width + x]; y < h; y++) {
900 memcpy(zbufp, p, w);
901 zbufp += w;
902 total += w;
903 p += gci->width;
904 }
905
906 rect.rr_encoding = htonl(RFBP_ENCODING_RAW);
907 nwrite = stream_write(c->rc_fd, &rect, sizeof (rect));
908 if (nwrite <= 0)
909 return (false);
910
911 return (stream_write(c->rc_fd, c->rc_zbuf, total) == total);
912 }
913
914
915 static bool
rfb_send_all(rfb_client_t * c,struct bhyvegc_image * gci)916 rfb_send_all(rfb_client_t *c, struct bhyvegc_image *gci)
917 {
918 rfb_rect_hdr_t rect;
919 ssize_t nwrite;
920 unsigned long zlen;
921 int err;
922
923 rfb_printf(c, RFB_LOGDEBUG, "send entire screen");
924
925 /* Just the one (big) rect. */
926 if (!rfb_send_update_header(c, 1))
927 return (false);
928
929 rect.rr_x = 0;
930 rect.rr_y = 0;
931 rect.rr_width = htons(gci->width);
932 rect.rr_height = htons(gci->height);
933
934 uint32_t *data = gci->data;
935 if (c->rc_custom_pixfmt) {
936 translate_pixels(c, gci, 0, 0, gci->width, gci->height);
937 data = c->rc_gci.data;
938 }
939
940 if (c->rc_encodings & RFB_ENCODING_ZLIB) {
941 c->rc_zstream.next_in = (Bytef *)data;
942 c->rc_zstream.avail_in = gci->width * gci->height *
943 sizeof (uint32_t);
944 c->rc_zstream.next_out = (Bytef *)c->rc_zbuf;
945 c->rc_zstream.avail_out = RFB_ZLIB_BUFSZ + 16;
946 c->rc_zstream.data_type = Z_BINARY;
947
948 c->rc_zstream.total_in = 0;
949 c->rc_zstream.total_out = 0;
950
951 /* Compress with zlib. */
952 err = deflate(&c->rc_zstream, Z_SYNC_FLUSH);
953 if (err != Z_OK) {
954 rfb_printf(c, RFB_LOGWARN, "zlib deflate err: %d", err);
955 goto doraw;
956 }
957
958 rect.rr_encoding = htonl(RFBP_ENCODING_ZLIB);
959 nwrite = stream_write(c->rc_fd, &rect, sizeof (rect));
960 if (nwrite <= 0)
961 return (false);
962
963 zlen = htonl(c->rc_zstream.total_out);
964 nwrite = stream_write(c->rc_fd, &zlen, sizeof (uint32_t));
965 if (nwrite <= 0)
966 return (false);
967 return (stream_write(c->rc_fd, c->rc_zbuf,
968 c->rc_zstream.total_out) == c->rc_zstream.total_out);
969 }
970
971 doraw:
972 rect.rr_encoding = htonl(RFBP_ENCODING_RAW);
973 nwrite = stream_write(c->rc_fd, &rect, sizeof (rect));
974 if (nwrite <= 0)
975 return (false);
976
977 nwrite = gci->width * gci->height * sizeof (uint32_t);
978 return (stream_write(c->rc_fd, data, nwrite) == nwrite);
979 }
980
981 static bool
rfb_send_screen(rfb_client_t * c)982 rfb_send_screen(rfb_client_t *c)
983 {
984 struct bhyvegc_image *gci;
985 bool retval = true;
986 bool sendall = false;
987 int xcells, ycells;
988 int rem_x, rem_y;
989 uint32_t *p, *ncrc, *ocrc;
990 uint_t changes, perc, x, y;
991
992 /* Updates require a preceding client update request. */
993 if (atomic_exchange(&c->rc_pending, false) == false)
994 return (true);
995
996 console_refresh();
997 gci = console_get_image();
998
999 /*
1000 * It's helpful if the image size or data address does not change
1001 * underneath us.
1002 */
1003 pthread_mutex_lock(&gci->mtx);
1004
1005 /* Check for screen resolution changes. */
1006 if (c->rc_width != gci->width ||
1007 c->rc_height != gci->height) {
1008 c->rc_width = gci->width;
1009 c->rc_height = gci->height;
1010 c->rc_crc_reset = true;
1011 c->rc_send_fullscreen = true;
1012
1013 /* If the client supports it, send a resize event. */
1014 if (c->rc_encodings & RFB_ENCODING_RESIZE) {
1015 rfb_send_resize_update_msg(c);
1016 /*
1017 * A resize message counts as an update in response to
1018 * the client's preceding request so rc->pending does
1019 * not need to be reset here.
1020 */
1021 goto done;
1022 }
1023 }
1024
1025 /* Clear old CRC values. */
1026 if (atomic_exchange(&c->rc_crc_reset, false))
1027 memset(c->rc_crc, '\0', c->rc_cells * sizeof (uint32_t));
1028
1029 if (c->rc_custom_pixfmt && (c->rc_gci.data == NULL ||
1030 c->rc_gci.width != c->rc_width ||
1031 c->rc_gci.height != c->rc_height)) {
1032 c->rc_gci.data = reallocarray(c->rc_gci.data,
1033 c->rc_width * c->rc_height, sizeof (uint32_t));
1034 if (c->rc_gci.data == NULL) {
1035 retval = false;
1036 goto done;
1037 }
1038 c->rc_gci.width = c->rc_width;
1039 c->rc_gci.height = c->rc_height;
1040 } else if (!c->rc_custom_pixfmt && c->rc_gci.data != NULL) {
1041 free(c->rc_gci.data);
1042 c->rc_gci.data = NULL;
1043 }
1044
1045 sendall = atomic_exchange(&c->rc_send_fullscreen, false);
1046
1047 /*
1048 * Calculate a checksum for each 32x32 cell. Send all that have
1049 * changed since the last scan.
1050 */
1051
1052 xcells = howmany(gci->width, RFB_PIX_PER_CELL);
1053 ycells = howmany(gci->height, RFB_PIX_PER_CELL);
1054 rem_x = gci->width & RFB_PIXCELL_MASK;
1055 rem_y = gci->height & RFB_PIXCELL_MASK;
1056 if (rem_y == 0)
1057 rem_y = RFB_PIX_PER_CELL;
1058
1059 p = gci->data;
1060
1061 ncrc = c->rc_crc_tmp - xcells;
1062 ocrc = c->rc_crc - xcells;
1063 changes = 0;
1064 memset(c->rc_crc_tmp, '\0', sizeof (uint32_t) * xcells * ycells);
1065 for (y = 0; y < gci->height; y++) {
1066 if ((y & RFB_PIXCELL_MASK) == 0) {
1067 ncrc += xcells;
1068 ocrc += xcells;
1069 }
1070
1071 for (x = 0; x < xcells; x++) {
1072 uint_t cellwidth;
1073
1074 if (x == xcells - 1 && rem_x > 0)
1075 cellwidth = rem_x;
1076 else
1077 cellwidth = RFB_PIX_PER_CELL;
1078
1079 if (rfb_sse42) {
1080 ncrc[x] = fast_crc32(p,
1081 cellwidth * sizeof (uint32_t), ncrc[x]);
1082 } else {
1083 ncrc[x] = (uint32_t)crc32(ncrc[x],
1084 (Bytef *)p, cellwidth * sizeof (uint32_t));
1085 }
1086
1087 p += cellwidth;
1088
1089 /* check for crc delta if last row in cell. */
1090 if ((y & RFB_PIXCELL_MASK) == RFB_PIXCELL_MASK ||
1091 y == gci->height - 1) {
1092 if (ocrc[x] != ncrc[x]) {
1093 ocrc[x] = ncrc[x];
1094 ncrc[x] = 1;
1095 changes++;
1096 } else {
1097 ncrc[x] = 0;
1098 }
1099 }
1100 }
1101 }
1102
1103 perc = (changes * 100) / (xcells * ycells);
1104 if (rfb_debug > 1 && changes > 0) {
1105 rfb_printf(c, RFB_LOGDEBUG,
1106 "scanned and found %u changed cell(s) - %u%%",
1107 changes, perc);
1108 }
1109
1110 /*
1111 * If there are no changes, don't send an update. Restore the pending
1112 * flag since we still owe the client an update.
1113 */
1114 if (!sendall && !changes) {
1115 c->rc_pending = true;
1116 goto done;
1117 }
1118
1119 /* If there are a lot of changes, send the whole screen. */
1120 if (perc >= RFB_SENDALL_THRESH)
1121 sendall = true;
1122
1123 if (sendall) {
1124 retval = rfb_send_all(c, gci);
1125 goto done;
1126 }
1127
1128 if (!rfb_send_update_header(c, changes)) {
1129 retval = false;
1130 goto done;
1131 }
1132
1133 /* Send the changed cells as separate rects. */
1134 ncrc = c->rc_crc_tmp;
1135 for (y = 0; y < gci->height; y += RFB_PIX_PER_CELL) {
1136 /* Previous cell's row. */
1137 int celly = (y >> RFB_PIXCELL_SHIFT);
1138
1139 /* Delta check crc to previous set. */
1140 for (x = 0; x < xcells; x++) {
1141 uint_t cellwidth;
1142
1143 if (*ncrc++ == 0)
1144 continue;
1145
1146 if (x == xcells - 1 && rem_x > 0)
1147 cellwidth = rem_x;
1148 else
1149 cellwidth = RFB_PIX_PER_CELL;
1150
1151 if (!rfb_send_rect(c, gci,
1152 x * RFB_PIX_PER_CELL, celly * RFB_PIX_PER_CELL,
1153 cellwidth, y + RFB_PIX_PER_CELL >= gci->height ?
1154 rem_y : RFB_PIX_PER_CELL)) {
1155 retval = false;
1156 goto done;
1157 }
1158 }
1159 }
1160
1161 done:
1162 pthread_mutex_unlock(&gci->mtx);
1163
1164 return (retval);
1165 }
1166
1167 static void *
rfb_client_rx_thread(void * arg)1168 rfb_client_rx_thread(void *arg)
1169 {
1170 rfb_client_t *c = arg;
1171 unsigned char cmd;
1172 bool ret = true;
1173
1174 while (ret && !c->rc_closing && (read(c->rc_fd, &cmd, 1) == 1)) {
1175 switch (cmd) {
1176 case RFBP_CS_SET_PIXEL_FORMAT:
1177 ret = rfb_recv_set_pixel_format(c);
1178 break;
1179 case RFBP_CS_SET_ENCODINGS:
1180 ret = rfb_recv_set_encodings(c);
1181 break;
1182 case RFBP_CS_UPDATE_REQUEST:
1183 ret = rfb_recv_update(c);
1184 break;
1185 case RFBP_CS_KEY_EVENT:
1186 ret = rfb_recv_key_event(c);
1187 break;
1188 case RFBP_CS_POINTER_EVENT:
1189 ret = rfb_recv_pointer_event(c);
1190 break;
1191 case RFBP_CS_CUT_TEXT:
1192 ret = rfb_recv_cut_text(c);
1193 break;
1194 case RFBP_CS_QEMU:
1195 ret = rfb_recv_qemu(c);
1196 break;
1197 default:
1198 rfb_printf(c, RFB_LOGWARN, "unknown cs code %d",
1199 cmd & 0xff);
1200 ret = false;
1201 }
1202 }
1203
1204 rfb_printf(c, RFB_LOGDEBUG, "client rx thread exiting");
1205 c->rc_closing = true;
1206
1207 return (NULL);
1208 }
1209
1210 static void *
rfb_client_tx_thread(void * arg)1211 rfb_client_tx_thread(void *arg)
1212 {
1213 rfb_client_t *c = arg;
1214 rfb_server_t *s = c->rc_s;
1215 char tname[MAXCOMLEN + 1];
1216 uint_t counter = 0;
1217 hrtime_t tprev;
1218 void *status;
1219 int err;
1220
1221 (void) snprintf(tname, sizeof (tname), "rfb%u tx", c->rc_instance);
1222 (void) pthread_set_name_np(c->rc_tx_tid, tname);
1223
1224 c->rc_sinfo.rsi_pixfmt = c->rc_s->rs_pixfmt;
1225 c->rc_encodings = RFB_ENCODING_RAW;
1226
1227 if (!rfb_handshake(c)) {
1228 rfb_printf(c, RFB_LOGWARN, "handshake failure");
1229 goto out;
1230 }
1231
1232 c->rc_cells = howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, RFB_PIX_PER_CELL);
1233 if ((c->rc_crc = calloc(c->rc_cells, sizeof (uint32_t))) == NULL ||
1234 (c->rc_crc_tmp = calloc(c->rc_cells, sizeof (uint32_t))) == NULL) {
1235 perror("calloc crc");
1236 goto out;
1237 }
1238
1239 err = pthread_create(&c->rc_rx_tid, NULL, rfb_client_rx_thread, c);
1240 if (err != 0) {
1241 perror("pthread_create client rx thread");
1242 goto out;
1243 }
1244
1245 (void) snprintf(tname, sizeof (tname), "rfb%u rx", c->rc_instance);
1246 (void) pthread_set_name_np(c->rc_rx_tid, tname);
1247
1248 tprev = gethrtime();
1249
1250 while (!c->rc_closing) {
1251 struct timeval tv;
1252 hrtime_t tnow;
1253 int64_t tdiff;
1254 fd_set rfds;
1255 int err;
1256
1257 FD_ZERO(&rfds);
1258 FD_SET(c->rc_fd, &rfds);
1259 tv.tv_sec = 0;
1260 tv.tv_usec = RFB_SEL_DELAY_US;
1261
1262 err = select(c->rc_fd + 1, &rfds, NULL, NULL, &tv);
1263 if (err < 0)
1264 break;
1265
1266 /* Determine if its time to push the screen; ~24hz. */
1267 tnow = gethrtime();
1268 tdiff = NSEC2USEC(tnow - tprev);
1269 if (tdiff >= RFB_SCREEN_POLL_DELAY) {
1270 bool input;
1271
1272 tprev = tnow;
1273
1274 input = atomic_exchange(&c->rc_input_detected, false);
1275 /*
1276 * Refresh the screen on every second trip through the
1277 * loop, or if keyboard/mouse input has been detected.
1278 */
1279 if ((++counter & 1) != 0 || input) {
1280 if (!rfb_send_screen(c))
1281 break;
1282 }
1283 } else {
1284 (void) usleep(RFB_SCREEN_POLL_DELAY - tdiff);
1285 }
1286 }
1287
1288 out:
1289
1290 rfb_printf(c, RFB_LOGWARN, "disconnected");
1291
1292 (void) pthread_join(c->rc_rx_tid, &status);
1293 pthread_mutex_lock(&s->rs_clientlock);
1294 s->rs_clientcount--;
1295 list_remove(&s->rs_clients, c);
1296 if (s->rs_exclusive && s->rs_clientcount == 0)
1297 s->rs_exclusive = false;
1298 id_free(rfb_idspace, c->rc_instance);
1299 pthread_mutex_unlock(&s->rs_clientlock);
1300
1301 rfb_free_client(c);
1302 return (NULL);
1303 }
1304
1305 static void
rfb_accept(int sfd,enum ev_type event,void * arg)1306 rfb_accept(int sfd, enum ev_type event, void *arg)
1307 {
1308 rfb_server_t *s = arg;
1309 rfb_client_t *c = NULL;
1310 struct sockaddr_storage cliaddr;
1311 socklen_t len;
1312 char host[NI_MAXHOST], port[NI_MAXSERV];
1313 int cfd, err;
1314 uint_t cc;
1315
1316 rfb_printf(c, RFB_LOGDEBUG, "incoming connection");
1317
1318 len = sizeof (cliaddr);
1319 cfd = accept(sfd, (struct sockaddr *)&cliaddr, &len);
1320 if (cfd == -1) {
1321 perror("client accept");
1322 return;
1323 }
1324
1325 *host = *port = '\0';
1326 if (cliaddr.ss_family == AF_UNIX) {
1327 rfb_printf(NULL, RFB_LOGDEBUG, "connection on UNIX socket");
1328 (void) strlcpy(host, "<UNIX>", sizeof (host));
1329 } else {
1330 err = getnameinfo((struct sockaddr *)&cliaddr, len,
1331 host, sizeof (host), port, sizeof (port),
1332 NI_NUMERICHOST | NI_NUMERICSERV);
1333 if (err != 0) {
1334 rfb_printf(NULL, RFB_LOGERR, "getnameinfo: %s",
1335 gai_strerror(err));
1336 *host = *port = '\0';
1337 } else {
1338 rfb_printf(NULL, RFB_LOGDEBUG, "connection from %s:%s",
1339 host, port);
1340 }
1341 }
1342
1343 pthread_mutex_lock(&s->rs_clientlock);
1344 cc = s->rs_clientcount;
1345 pthread_mutex_unlock(&s->rs_clientlock);
1346 if (cc >= RFB_MAX_CLIENTS) {
1347 rfb_printf(NULL, RFB_LOGERR,
1348 "too many clients, closing connection.");
1349 goto fail;
1350 }
1351
1352 if ((c = calloc(1, sizeof (rfb_client_t))) == NULL) {
1353 perror("calloc client");
1354 goto fail;
1355 }
1356
1357 c->rc_fd = cfd;
1358 c->rc_s = s;
1359 c->rc_zbuf = malloc(RFB_ZLIB_BUFSZ + 16);
1360 if (c->rc_zbuf == NULL)
1361 goto fail;
1362
1363 pthread_mutex_lock(&s->rs_clientlock);
1364
1365 err = pthread_create(&c->rc_tx_tid, NULL, rfb_client_tx_thread, c);
1366 if (err != 0) {
1367 perror("pthread_create client tx thread");
1368 pthread_mutex_unlock(&s->rs_clientlock);
1369 goto fail;
1370 }
1371
1372 s->rs_clientcount++;
1373 list_insert_tail(&s->rs_clients, c);
1374 c->rc_instance = id_allocff(rfb_idspace);
1375 pthread_mutex_unlock(&s->rs_clientlock);
1376
1377 (void) pthread_detach(c->rc_tx_tid);
1378
1379 rfb_printf(c, RFB_LOGWARN, "connection from %s", host);
1380
1381 return;
1382
1383 fail:
1384 (void) close(cfd);
1385 free(c);
1386 }
1387
1388 int
rfb_init(char * hostname,int port,int wait,const char * password,const char * name)1389 rfb_init(char *hostname, int port, int wait, const char *password,
1390 const char *name)
1391 {
1392 rfb_server_t *s;
1393 #ifndef WITHOUT_CAPSICUM
1394 cap_rights_t rights;
1395 #endif
1396
1397 (void) pthread_once(&rfb_once, rfb_init_once);
1398
1399 if (rfb_idspace == NULL) {
1400 rfb_printf(NULL, RFB_LOGERR,
1401 "rfb_idspace could not be allocated");
1402 return (-1);
1403 }
1404
1405 if ((s = calloc(1, sizeof (rfb_server_t))) == NULL) {
1406 perror("calloc");
1407 return (-1);
1408 }
1409 s->rs_fd = -1;
1410 s->rs_name = name;
1411
1412 if (password != NULL && strlen(password) > 0)
1413 s->rs_password = password;
1414
1415 if (pthread_mutex_init(&s->rs_clientlock, NULL) != 0) {
1416 perror("pthread_mutex_init");
1417 free(s);
1418 return (-1);
1419 }
1420
1421 list_create(&s->rs_clients, sizeof (rfb_client_t),
1422 offsetof(rfb_client_t, rc_node));
1423
1424 /* Server pixel format. */
1425 s->rs_pixfmt.rp_bpp = RFB_PIX_BPP;
1426 s->rs_pixfmt.rp_depth = RFB_PIX_DEPTH;
1427 s->rs_pixfmt.rp_bigendian = 0;
1428 s->rs_pixfmt.rp_truecolour = 1;
1429 s->rs_pixfmt.rp_r_max = htons(RFB_PIX_RMAX);
1430 s->rs_pixfmt.rp_g_max = htons(RFB_PIX_GMAX);
1431 s->rs_pixfmt.rp_b_max = htons(RFB_PIX_BMAX);
1432 s->rs_pixfmt.rp_r_shift = RFB_PIX_RSHIFT;
1433 s->rs_pixfmt.rp_g_shift = RFB_PIX_GSHIFT;
1434 s->rs_pixfmt.rp_b_shift = RFB_PIX_BSHIFT;
1435
1436 /* UNIX socket. */
1437 if (port == -1 && hostname != NULL && *hostname == '/') {
1438 struct sockaddr_un sock;
1439
1440 s->rs_fd = socket(PF_UNIX, SOCK_STREAM, 0);
1441 if (s->rs_fd < 0) {
1442 perror("socket");
1443 goto fail;
1444 }
1445
1446 sock.sun_family = AF_UNIX;
1447 if (strlcpy(sock.sun_path, hostname, sizeof (sock.sun_path)) >=
1448 sizeof (sock.sun_path)) {
1449 rfb_printf(NULL, RFB_LOGERR,
1450 "socket path '%s' too long\n", hostname);
1451 goto fail;
1452 }
1453
1454 (void) unlink(hostname);
1455 if (bind(s->rs_fd, (struct sockaddr *)&sock,
1456 sizeof (sock)) < 0) {
1457 perror("bind");
1458 goto fail;
1459 }
1460 } else {
1461 struct addrinfo hints, *ai = NULL;
1462 char servname[6];
1463 int e;
1464
1465 (void) snprintf(servname, sizeof (servname), "%d",
1466 port ? port : RFB_DEFAULT_PORT);
1467
1468 if (hostname == NULL || strlen(hostname) == 0) {
1469 #if defined(INET)
1470 hostname = "127.0.0.1";
1471 #elif defined(INET6)
1472 hostname = "[::1]";
1473 #endif
1474 }
1475
1476 memset(&hints, '\0', sizeof (hints));
1477 hints.ai_family = AF_UNSPEC;
1478 hints.ai_socktype = SOCK_STREAM;
1479 hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE;
1480
1481 if ((e = getaddrinfo(hostname, servname, &hints, &ai)) != 0) {
1482 rfb_printf(NULL, RFB_LOGERR, "getaddrinfo: %s",
1483 gai_strerror(e));
1484 goto fail;
1485 }
1486
1487 s->rs_fd = socket(ai->ai_family, ai->ai_socktype, 0);
1488 if (s->rs_fd < 0) {
1489 perror("socket");
1490 freeaddrinfo(ai);
1491 goto fail;
1492 }
1493
1494 e = 1;
1495 (void) setsockopt(s->rs_fd, SOL_SOCKET, SO_REUSEADDR,
1496 &e, sizeof (e));
1497
1498 if (bind(s->rs_fd, ai->ai_addr, ai->ai_addrlen) < 0) {
1499 perror("bind");
1500 freeaddrinfo(ai);
1501 goto fail;
1502 }
1503 freeaddrinfo(ai);
1504 }
1505
1506 if (listen(s->rs_fd, 5) < 0) {
1507 perror("listen");
1508 goto fail;
1509 }
1510
1511 #ifndef WITHOUT_CAPSICUM
1512 cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE);
1513 if (caph_rights_limit(s->rs_fd, &rights) == -1)
1514 errx(EX_OSERR, "Unable to apply rights for sandbox");
1515 #endif
1516
1517 s->rs_connevent = mevent_add(s->rs_fd, EVF_READ, rfb_accept, s);
1518 if (s->rs_connevent == NULL) {
1519 rfb_printf(NULL, RFB_LOGERR,
1520 "Failed to set up rfb connection mevent");
1521 goto fail;
1522 }
1523
1524 list_insert_tail(&rfb_list, s);
1525
1526 /*
1527 * Wait for first connection. Since the mevent thread is
1528 * not yet running, we can't rely on normal incoming connection
1529 * handling.
1530 */
1531 if (wait != 0) {
1532 fd_set rfds;
1533 int e;
1534
1535 rfb_printf(NULL, RFB_LOGWARN,
1536 "holding boot until first client connection");
1537
1538 for (;;) {
1539 FD_ZERO(&rfds);
1540 FD_SET(s->rs_fd, &rfds);
1541
1542 e = select(s->rs_fd + 1, &rfds, NULL, NULL, NULL);
1543 if (e < 0 && errno == EINTR)
1544 continue;
1545 if (e < 0 || FD_ISSET(s->rs_fd, &rfds))
1546 break;
1547 }
1548 rfb_printf(NULL, RFB_LOGWARN, "continuing boot");
1549 }
1550
1551 return (0);
1552
1553 fail:
1554 if (s->rs_fd != -1)
1555 VERIFY3S(close(s->rs_fd), ==, 0);
1556 (void) pthread_mutex_destroy(&s->rs_clientlock);
1557 list_destroy(&s->rs_clients);
1558 free(s);
1559 return (-1);
1560 }
1561