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