1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 * 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 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 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