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 * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include <sys/param.h> 36 #ifndef WITHOUT_CAPSICUM 37 #include <sys/capsicum.h> 38 #endif 39 #include <sys/endian.h> 40 #include <sys/socket.h> 41 #include <sys/select.h> 42 #include <sys/time.h> 43 #include <arpa/inet.h> 44 #include <stdatomic.h> 45 #include <machine/cpufunc.h> 46 #include <machine/specialreg.h> 47 #include <netinet/in.h> 48 #include <netdb.h> 49 50 #include <assert.h> 51 #ifndef WITHOUT_CAPSICUM 52 #include <capsicum_helpers.h> 53 #endif 54 #include <err.h> 55 #include <errno.h> 56 #include <pthread.h> 57 #include <pthread_np.h> 58 #include <signal.h> 59 #include <stdbool.h> 60 #include <stdlib.h> 61 #include <stdio.h> 62 #include <string.h> 63 #include <sysexits.h> 64 #include <unistd.h> 65 66 #include <zlib.h> 67 68 #ifndef __FreeBSD__ 69 #include <sys/debug.h> 70 #endif 71 72 #include "bhyvegc.h" 73 #include "debug.h" 74 #include "console.h" 75 #include "rfb.h" 76 #include "sockstream.h" 77 78 #ifndef NO_OPENSSL 79 #include <openssl/des.h> 80 #endif 81 82 /* Delays in microseconds */ 83 #define CFD_SEL_DELAY 10000 84 #define SCREEN_REFRESH_DELAY 33300 /* 30Hz */ 85 #define SCREEN_POLL_DELAY (SCREEN_REFRESH_DELAY / 2) 86 87 static int rfb_debug = 0; 88 #define DPRINTF(params) if (rfb_debug) PRINTLN params 89 #define WPRINTF(params) PRINTLN params 90 91 #define VERSION_LENGTH 12 92 #define AUTH_LENGTH 16 93 #define PASSWD_LENGTH 8 94 95 /* Protocol versions */ 96 #define CVERS_3_3 '3' 97 #define CVERS_3_7 '7' 98 #define CVERS_3_8 '8' 99 100 /* Client-to-server msg types */ 101 #define CS_SET_PIXEL_FORMAT 0 102 #define CS_SET_ENCODINGS 2 103 #define CS_UPDATE_MSG 3 104 #define CS_KEY_EVENT 4 105 #define CS_POINTER_EVENT 5 106 #define CS_CUT_TEXT 6 107 108 #define SECURITY_TYPE_NONE 1 109 #define SECURITY_TYPE_VNC_AUTH 2 110 111 #define AUTH_FAILED_UNAUTH 1 112 #define AUTH_FAILED_ERROR 2 113 114 struct rfb_softc { 115 int sfd; 116 pthread_t tid; 117 118 int cfd; 119 120 int width, height; 121 122 char *password; 123 124 bool enc_raw_ok; 125 bool enc_zlib_ok; 126 bool enc_resize_ok; 127 128 z_stream zstream; 129 uint8_t *zbuf; 130 int zbuflen; 131 132 int conn_wait; 133 int wrcount; 134 135 atomic_bool sending; 136 atomic_bool pending; 137 atomic_bool update_all; 138 atomic_bool input_detected; 139 140 pthread_mutex_t mtx; 141 pthread_cond_t cond; 142 143 int hw_crc; 144 uint32_t *crc; /* WxH crc cells */ 145 uint32_t *crc_tmp; /* buffer to store single crc row */ 146 int crc_width, crc_height; 147 #ifndef __FreeBSD__ 148 const char *name; 149 #endif 150 }; 151 152 struct rfb_pixfmt { 153 uint8_t bpp; 154 uint8_t depth; 155 uint8_t bigendian; 156 uint8_t truecolor; 157 uint16_t red_max; 158 uint16_t green_max; 159 uint16_t blue_max; 160 uint8_t red_shift; 161 uint8_t green_shift; 162 uint8_t blue_shift; 163 uint8_t pad[3]; 164 }; 165 166 struct rfb_srvr_info { 167 uint16_t width; 168 uint16_t height; 169 struct rfb_pixfmt pixfmt; 170 uint32_t namelen; 171 }; 172 173 struct rfb_pixfmt_msg { 174 uint8_t type; 175 uint8_t pad[3]; 176 struct rfb_pixfmt pixfmt; 177 }; 178 179 #define RFB_ENCODING_RAW 0 180 #define RFB_ENCODING_ZLIB 6 181 #define RFB_ENCODING_RESIZE -223 182 183 #define RFB_MAX_WIDTH 2000 184 #define RFB_MAX_HEIGHT 1200 185 #define RFB_ZLIB_BUFSZ RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4 186 187 /* percentage changes to screen before sending the entire screen */ 188 #define RFB_SEND_ALL_THRESH 25 189 190 struct rfb_enc_msg { 191 uint8_t type; 192 uint8_t pad; 193 uint16_t numencs; 194 }; 195 196 struct rfb_updt_msg { 197 uint8_t type; 198 uint8_t incremental; 199 uint16_t x; 200 uint16_t y; 201 uint16_t width; 202 uint16_t height; 203 }; 204 205 struct rfb_key_msg { 206 uint8_t type; 207 uint8_t down; 208 uint16_t pad; 209 uint32_t code; 210 }; 211 212 struct rfb_ptr_msg { 213 uint8_t type; 214 uint8_t button; 215 uint16_t x; 216 uint16_t y; 217 }; 218 219 struct rfb_srvr_updt_msg { 220 uint8_t type; 221 uint8_t pad; 222 uint16_t numrects; 223 }; 224 225 struct rfb_srvr_rect_hdr { 226 uint16_t x; 227 uint16_t y; 228 uint16_t width; 229 uint16_t height; 230 uint32_t encoding; 231 }; 232 233 struct rfb_cuttext_msg { 234 uint8_t type; 235 uint8_t padding[3]; 236 uint32_t length; 237 }; 238 239 static void 240 #ifndef __FreeBSD__ 241 rfb_send_server_init_msg(int cfd, struct rfb_softc *rc) 242 #else 243 rfb_send_server_init_msg(int cfd) 244 #endif 245 { 246 struct bhyvegc_image *gc_image; 247 struct rfb_srvr_info sinfo; 248 249 gc_image = console_get_image(); 250 251 sinfo.width = htons(gc_image->width); 252 sinfo.height = htons(gc_image->height); 253 sinfo.pixfmt.bpp = 32; 254 sinfo.pixfmt.depth = 32; 255 sinfo.pixfmt.bigendian = 0; 256 sinfo.pixfmt.truecolor = 1; 257 sinfo.pixfmt.red_max = htons(255); 258 sinfo.pixfmt.green_max = htons(255); 259 sinfo.pixfmt.blue_max = htons(255); 260 sinfo.pixfmt.red_shift = 16; 261 sinfo.pixfmt.green_shift = 8; 262 sinfo.pixfmt.blue_shift = 0; 263 sinfo.pixfmt.pad[0] = 0; 264 sinfo.pixfmt.pad[1] = 0; 265 sinfo.pixfmt.pad[2] = 0; 266 267 #ifndef __FreeBSD__ 268 const char *name = rc->name != NULL ? rc->name : "bhyve"; 269 270 sinfo.namelen = htonl(strlen(name)); 271 (void)stream_write(cfd, &sinfo, sizeof(sinfo)); 272 (void)stream_write(cfd, name, strlen(name)); 273 #else 274 sinfo.namelen = htonl(strlen("bhyve")); 275 (void)stream_write(cfd, &sinfo, sizeof(sinfo)); 276 (void)stream_write(cfd, "bhyve", strlen("bhyve")); 277 #endif 278 } 279 280 static void 281 rfb_send_resize_update_msg(struct rfb_softc *rc, int cfd) 282 { 283 struct rfb_srvr_updt_msg supdt_msg; 284 struct rfb_srvr_rect_hdr srect_hdr; 285 286 /* Number of rectangles: 1 */ 287 supdt_msg.type = 0; 288 supdt_msg.pad = 0; 289 supdt_msg.numrects = htons(1); 290 stream_write(cfd, &supdt_msg, sizeof(struct rfb_srvr_updt_msg)); 291 292 /* Rectangle header */ 293 srect_hdr.x = htons(0); 294 srect_hdr.y = htons(0); 295 srect_hdr.width = htons(rc->width); 296 srect_hdr.height = htons(rc->height); 297 srect_hdr.encoding = htonl(RFB_ENCODING_RESIZE); 298 stream_write(cfd, &srect_hdr, sizeof(struct rfb_srvr_rect_hdr)); 299 } 300 301 static void 302 rfb_recv_set_pixfmt_msg(struct rfb_softc *rc, int cfd) 303 { 304 struct rfb_pixfmt_msg pixfmt_msg; 305 306 (void)stream_read(cfd, ((void *)&pixfmt_msg)+1, sizeof(pixfmt_msg)-1); 307 } 308 309 310 static void 311 rfb_recv_set_encodings_msg(struct rfb_softc *rc, int cfd) 312 { 313 struct rfb_enc_msg enc_msg; 314 int i; 315 uint32_t encoding; 316 317 (void)stream_read(cfd, ((void *)&enc_msg)+1, sizeof(enc_msg)-1); 318 319 for (i = 0; i < htons(enc_msg.numencs); i++) { 320 (void)stream_read(cfd, &encoding, sizeof(encoding)); 321 switch (htonl(encoding)) { 322 case RFB_ENCODING_RAW: 323 rc->enc_raw_ok = true; 324 break; 325 case RFB_ENCODING_ZLIB: 326 if (!rc->enc_zlib_ok) { 327 deflateInit(&rc->zstream, Z_BEST_SPEED); 328 rc->enc_zlib_ok = true; 329 } 330 break; 331 case RFB_ENCODING_RESIZE: 332 rc->enc_resize_ok = true; 333 break; 334 } 335 } 336 } 337 338 /* 339 * Calculate CRC32 using SSE4.2; Intel or AMD Bulldozer+ CPUs only 340 */ 341 static __inline uint32_t 342 fast_crc32(void *buf, int len, uint32_t crcval) 343 { 344 uint32_t q = len / sizeof(uint32_t); 345 uint32_t *p = (uint32_t *)buf; 346 347 while (q--) { 348 asm volatile ( 349 ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;" 350 :"=S" (crcval) 351 :"0" (crcval), "c" (*p) 352 ); 353 p++; 354 } 355 356 return (crcval); 357 } 358 359 static int 360 rfb_send_update_header(struct rfb_softc *rc, int cfd, int numrects) 361 { 362 struct rfb_srvr_updt_msg supdt_msg; 363 364 supdt_msg.type = 0; 365 supdt_msg.pad = 0; 366 supdt_msg.numrects = htons(numrects); 367 368 return stream_write(cfd, &supdt_msg, 369 sizeof(struct rfb_srvr_updt_msg)); 370 } 371 372 static int 373 rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc, 374 int x, int y, int w, int h) 375 { 376 struct rfb_srvr_rect_hdr srect_hdr; 377 unsigned long zlen; 378 ssize_t nwrite, total; 379 int err; 380 uint32_t *p; 381 uint8_t *zbufp; 382 383 /* 384 * Send a single rectangle of the given x, y, w h dimensions. 385 */ 386 387 /* Rectangle header */ 388 srect_hdr.x = htons(x); 389 srect_hdr.y = htons(y); 390 srect_hdr.width = htons(w); 391 srect_hdr.height = htons(h); 392 393 h = y + h; 394 w *= sizeof(uint32_t); 395 if (rc->enc_zlib_ok) { 396 zbufp = rc->zbuf; 397 rc->zstream.total_in = 0; 398 rc->zstream.total_out = 0; 399 for (p = &gc->data[y * gc->width + x]; y < h; y++) { 400 rc->zstream.next_in = (Bytef *)p; 401 rc->zstream.avail_in = w; 402 rc->zstream.next_out = (Bytef *)zbufp; 403 rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16 - 404 rc->zstream.total_out; 405 rc->zstream.data_type = Z_BINARY; 406 407 /* Compress with zlib */ 408 err = deflate(&rc->zstream, Z_SYNC_FLUSH); 409 if (err != Z_OK) { 410 WPRINTF(("zlib[rect] deflate err: %d", err)); 411 rc->enc_zlib_ok = false; 412 deflateEnd(&rc->zstream); 413 goto doraw; 414 } 415 zbufp = rc->zbuf + rc->zstream.total_out; 416 p += gc->width; 417 } 418 srect_hdr.encoding = htonl(RFB_ENCODING_ZLIB); 419 nwrite = stream_write(cfd, &srect_hdr, 420 sizeof(struct rfb_srvr_rect_hdr)); 421 if (nwrite <= 0) 422 return (nwrite); 423 424 zlen = htonl(rc->zstream.total_out); 425 nwrite = stream_write(cfd, &zlen, sizeof(uint32_t)); 426 if (nwrite <= 0) 427 return (nwrite); 428 return (stream_write(cfd, rc->zbuf, rc->zstream.total_out)); 429 } 430 431 doraw: 432 433 total = 0; 434 zbufp = rc->zbuf; 435 for (p = &gc->data[y * gc->width + x]; y < h; y++) { 436 memcpy(zbufp, p, w); 437 zbufp += w; 438 total += w; 439 p += gc->width; 440 } 441 442 srect_hdr.encoding = htonl(RFB_ENCODING_RAW); 443 nwrite = stream_write(cfd, &srect_hdr, 444 sizeof(struct rfb_srvr_rect_hdr)); 445 if (nwrite <= 0) 446 return (nwrite); 447 448 total = stream_write(cfd, rc->zbuf, total); 449 450 return (total); 451 } 452 453 static int 454 rfb_send_all(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc) 455 { 456 struct rfb_srvr_updt_msg supdt_msg; 457 struct rfb_srvr_rect_hdr srect_hdr; 458 ssize_t nwrite; 459 unsigned long zlen; 460 int err; 461 462 /* 463 * Send the whole thing 464 */ 465 466 /* Number of rectangles: 1 */ 467 supdt_msg.type = 0; 468 supdt_msg.pad = 0; 469 supdt_msg.numrects = htons(1); 470 nwrite = stream_write(cfd, &supdt_msg, 471 sizeof(struct rfb_srvr_updt_msg)); 472 if (nwrite <= 0) 473 return (nwrite); 474 475 /* Rectangle header */ 476 srect_hdr.x = 0; 477 srect_hdr.y = 0; 478 srect_hdr.width = htons(gc->width); 479 srect_hdr.height = htons(gc->height); 480 if (rc->enc_zlib_ok) { 481 rc->zstream.next_in = (Bytef *)gc->data; 482 rc->zstream.avail_in = gc->width * gc->height * 483 sizeof(uint32_t); 484 rc->zstream.next_out = (Bytef *)rc->zbuf; 485 rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16; 486 rc->zstream.data_type = Z_BINARY; 487 488 rc->zstream.total_in = 0; 489 rc->zstream.total_out = 0; 490 491 /* Compress with zlib */ 492 err = deflate(&rc->zstream, Z_SYNC_FLUSH); 493 if (err != Z_OK) { 494 WPRINTF(("zlib deflate err: %d", err)); 495 rc->enc_zlib_ok = false; 496 deflateEnd(&rc->zstream); 497 goto doraw; 498 } 499 500 srect_hdr.encoding = htonl(RFB_ENCODING_ZLIB); 501 nwrite = stream_write(cfd, &srect_hdr, 502 sizeof(struct rfb_srvr_rect_hdr)); 503 if (nwrite <= 0) 504 return (nwrite); 505 506 zlen = htonl(rc->zstream.total_out); 507 nwrite = stream_write(cfd, &zlen, sizeof(uint32_t)); 508 if (nwrite <= 0) 509 return (nwrite); 510 return (stream_write(cfd, rc->zbuf, rc->zstream.total_out)); 511 } 512 513 doraw: 514 srect_hdr.encoding = htonl(RFB_ENCODING_RAW); 515 nwrite = stream_write(cfd, &srect_hdr, 516 sizeof(struct rfb_srvr_rect_hdr)); 517 if (nwrite <= 0) 518 return (nwrite); 519 520 nwrite = stream_write(cfd, gc->data, 521 gc->width * gc->height * sizeof(uint32_t)); 522 523 return (nwrite); 524 } 525 526 #define PIX_PER_CELL 32 527 #define PIXCELL_SHIFT 5 528 #define PIXCELL_MASK 0x1F 529 530 static int 531 rfb_send_screen(struct rfb_softc *rc, int cfd) 532 { 533 struct bhyvegc_image *gc_image; 534 ssize_t nwrite; 535 int x, y; 536 int celly, cellwidth; 537 int xcells, ycells; 538 int w, h; 539 uint32_t *p; 540 int rem_x, rem_y; /* remainder for resolutions not x32 pixels ratio */ 541 int retval; 542 uint32_t *crc_p, *orig_crc; 543 int changes; 544 bool expected; 545 546 /* Return if another thread sending */ 547 expected = false; 548 if (atomic_compare_exchange_strong(&rc->sending, &expected, true) == false) 549 return (1); 550 551 retval = 1; 552 553 /* Updates require a preceding update request */ 554 if (atomic_exchange(&rc->pending, false) == false) 555 goto done; 556 557 console_refresh(); 558 gc_image = console_get_image(); 559 560 /* Clear old CRC values when the size changes */ 561 if (rc->crc_width != gc_image->width || 562 rc->crc_height != gc_image->height) { 563 memset(rc->crc, 0, sizeof(uint32_t) * 564 howmany(RFB_MAX_WIDTH, PIX_PER_CELL) * 565 howmany(RFB_MAX_HEIGHT, PIX_PER_CELL)); 566 rc->crc_width = gc_image->width; 567 rc->crc_height = gc_image->height; 568 } 569 570 /* A size update counts as an update in itself */ 571 if (rc->width != gc_image->width || 572 rc->height != gc_image->height) { 573 rc->width = gc_image->width; 574 rc->height = gc_image->height; 575 if (rc->enc_resize_ok) { 576 rfb_send_resize_update_msg(rc, cfd); 577 rc->update_all = true; 578 goto done; 579 } 580 } 581 582 if (atomic_exchange(&rc->update_all, false) == true) { 583 retval = rfb_send_all(rc, cfd, gc_image); 584 goto done; 585 } 586 587 /* 588 * Calculate the checksum for each 32x32 cell. Send each that 589 * has changed since the last scan. 590 */ 591 592 w = rc->crc_width; 593 h = rc->crc_height; 594 xcells = howmany(rc->crc_width, PIX_PER_CELL); 595 ycells = howmany(rc->crc_height, PIX_PER_CELL); 596 597 rem_x = w & PIXCELL_MASK; 598 599 rem_y = h & PIXCELL_MASK; 600 if (!rem_y) 601 rem_y = PIX_PER_CELL; 602 603 p = gc_image->data; 604 605 /* 606 * Go through all cells and calculate crc. If significant number 607 * of changes, then send entire screen. 608 * crc_tmp is dual purpose: to store the new crc and to flag as 609 * a cell that has changed. 610 */ 611 crc_p = rc->crc_tmp - xcells; 612 orig_crc = rc->crc - xcells; 613 changes = 0; 614 memset(rc->crc_tmp, 0, sizeof(uint32_t) * xcells * ycells); 615 for (y = 0; y < h; y++) { 616 if ((y & PIXCELL_MASK) == 0) { 617 crc_p += xcells; 618 orig_crc += xcells; 619 } 620 621 for (x = 0; x < xcells; x++) { 622 if (x == (xcells - 1) && rem_x > 0) 623 cellwidth = rem_x; 624 else 625 cellwidth = PIX_PER_CELL; 626 627 if (rc->hw_crc) 628 crc_p[x] = fast_crc32(p, 629 cellwidth * sizeof(uint32_t), 630 crc_p[x]); 631 else 632 crc_p[x] = (uint32_t)crc32(crc_p[x], 633 (Bytef *)p, 634 cellwidth * sizeof(uint32_t)); 635 636 p += cellwidth; 637 638 /* check for crc delta if last row in cell */ 639 if ((y & PIXCELL_MASK) == PIXCELL_MASK || y == (h-1)) { 640 if (orig_crc[x] != crc_p[x]) { 641 orig_crc[x] = crc_p[x]; 642 crc_p[x] = 1; 643 changes++; 644 } else { 645 crc_p[x] = 0; 646 } 647 } 648 } 649 } 650 651 /* 652 * We only send the update if there are changes. 653 * Restore the pending flag since it was unconditionally cleared 654 * above. 655 */ 656 if (!changes) { 657 rc->pending = true; 658 goto done; 659 } 660 661 /* If number of changes is > THRESH percent, send the whole screen */ 662 if (((changes * 100) / (xcells * ycells)) >= RFB_SEND_ALL_THRESH) { 663 retval = rfb_send_all(rc, cfd, gc_image); 664 goto done; 665 } 666 667 rfb_send_update_header(rc, cfd, changes); 668 669 /* Go through all cells, and send only changed ones */ 670 crc_p = rc->crc_tmp; 671 for (y = 0; y < h; y += PIX_PER_CELL) { 672 /* previous cell's row */ 673 celly = (y >> PIXCELL_SHIFT); 674 675 /* Delta check crc to previous set */ 676 for (x = 0; x < xcells; x++) { 677 if (*crc_p++ == 0) 678 continue; 679 680 if (x == (xcells - 1) && rem_x > 0) 681 cellwidth = rem_x; 682 else 683 cellwidth = PIX_PER_CELL; 684 nwrite = rfb_send_rect(rc, cfd, 685 gc_image, 686 x * PIX_PER_CELL, 687 celly * PIX_PER_CELL, 688 cellwidth, 689 y + PIX_PER_CELL >= h ? rem_y : PIX_PER_CELL); 690 if (nwrite <= 0) { 691 retval = nwrite; 692 goto done; 693 } 694 } 695 } 696 697 done: 698 rc->sending = false; 699 700 return (retval); 701 } 702 703 704 static void 705 rfb_recv_update_msg(struct rfb_softc *rc, int cfd) 706 { 707 struct rfb_updt_msg updt_msg; 708 709 (void)stream_read(cfd, ((void *)&updt_msg) + 1 , sizeof(updt_msg) - 1); 710 711 rc->pending = true; 712 if (!updt_msg.incremental) 713 rc->update_all = true; 714 } 715 716 static void 717 rfb_recv_key_msg(struct rfb_softc *rc, int cfd) 718 { 719 struct rfb_key_msg key_msg; 720 721 (void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1); 722 723 console_key_event(key_msg.down, htonl(key_msg.code)); 724 rc->input_detected = true; 725 } 726 727 static void 728 rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd) 729 { 730 struct rfb_ptr_msg ptr_msg; 731 732 (void)stream_read(cfd, ((void *)&ptr_msg) + 1, sizeof(ptr_msg) - 1); 733 734 console_ptr_event(ptr_msg.button, htons(ptr_msg.x), htons(ptr_msg.y)); 735 rc->input_detected = true; 736 } 737 738 static void 739 rfb_recv_cuttext_msg(struct rfb_softc *rc, int cfd) 740 { 741 struct rfb_cuttext_msg ct_msg; 742 unsigned char buf[32]; 743 int len; 744 745 len = stream_read(cfd, ((void *)&ct_msg) + 1, sizeof(ct_msg) - 1); 746 ct_msg.length = htonl(ct_msg.length); 747 while (ct_msg.length > 0) { 748 len = stream_read(cfd, buf, ct_msg.length > sizeof(buf) ? 749 sizeof(buf) : ct_msg.length); 750 ct_msg.length -= len; 751 } 752 } 753 754 static int64_t 755 timeval_delta(struct timeval *prev, struct timeval *now) 756 { 757 int64_t n1, n2; 758 n1 = now->tv_sec * 1000000 + now->tv_usec; 759 n2 = prev->tv_sec * 1000000 + prev->tv_usec; 760 return (n1 - n2); 761 } 762 763 static void * 764 rfb_wr_thr(void *arg) 765 { 766 struct rfb_softc *rc; 767 fd_set rfds; 768 struct timeval tv; 769 struct timeval prev_tv; 770 int64_t tdiff; 771 int cfd; 772 int err; 773 774 rc = arg; 775 cfd = rc->cfd; 776 777 prev_tv.tv_sec = 0; 778 prev_tv.tv_usec = 0; 779 while (rc->cfd >= 0) { 780 FD_ZERO(&rfds); 781 FD_SET(cfd, &rfds); 782 tv.tv_sec = 0; 783 tv.tv_usec = CFD_SEL_DELAY; 784 785 err = select(cfd+1, &rfds, NULL, NULL, &tv); 786 if (err < 0) 787 return (NULL); 788 789 /* Determine if its time to push screen; ~24hz */ 790 gettimeofday(&tv, NULL); 791 tdiff = timeval_delta(&prev_tv, &tv); 792 if (tdiff >= SCREEN_POLL_DELAY) { 793 bool input; 794 prev_tv.tv_sec = tv.tv_sec; 795 prev_tv.tv_usec = tv.tv_usec; 796 input = atomic_exchange(&rc->input_detected, false); 797 /* 798 * Refresh the screen on every second trip through the loop, 799 * or if keyboard/mouse input has been detected. 800 */ 801 if ((++rc->wrcount & 1) || input) { 802 if (rfb_send_screen(rc, cfd) <= 0) { 803 return (NULL); 804 } 805 } 806 } else { 807 /* sleep */ 808 usleep(SCREEN_POLL_DELAY - tdiff); 809 } 810 } 811 812 return (NULL); 813 } 814 815 void 816 rfb_handle(struct rfb_softc *rc, int cfd) 817 { 818 const char *vbuf = "RFB 003.008\n"; 819 unsigned char buf[80]; 820 unsigned char *message = NULL; 821 822 #ifndef NO_OPENSSL 823 unsigned char challenge[AUTH_LENGTH]; 824 unsigned char keystr[PASSWD_LENGTH]; 825 unsigned char crypt_expected[AUTH_LENGTH]; 826 827 DES_key_schedule ks; 828 int i; 829 #endif 830 uint8_t client_ver; 831 uint8_t auth_type; 832 pthread_t tid; 833 uint32_t sres = 0; 834 int len; 835 int perror = 1; 836 837 rc->cfd = cfd; 838 839 /* 1a. Send server version */ 840 stream_write(cfd, vbuf, strlen(vbuf)); 841 842 /* 1b. Read client version */ 843 len = stream_read(cfd, buf, VERSION_LENGTH); 844 #ifdef __FreeBSD__ 845 if (len == VERSION_LENGTH && !strncmp(vbuf, buf, VERSION_LENGTH - 2)) { 846 client_ver = buf[VERSION_LENGTH - 2]; 847 } 848 #else 849 /* Work around gcc7 maybe-uninitialized warning */ 850 client_ver = CVERS_3_3; 851 if (len == VERSION_LENGTH && !strncmp(vbuf, (char *)buf, 852 VERSION_LENGTH - 2)) { 853 client_ver = buf[VERSION_LENGTH - 2]; 854 } 855 #endif 856 if (client_ver != CVERS_3_8 && client_ver != CVERS_3_7) { 857 /* only recognize 3.3, 3.7 & 3.8. Others dflt to 3.3 */ 858 client_ver = CVERS_3_3; 859 } 860 861 /* 2a. Send security type */ 862 buf[0] = 1; 863 864 /* In versions 3.7 & 3.8, it's 2-way handshake */ 865 /* For version 3.3, server says what the authentication type must be */ 866 #ifndef NO_OPENSSL 867 if (rc->password) { 868 auth_type = SECURITY_TYPE_VNC_AUTH; 869 } else { 870 auth_type = SECURITY_TYPE_NONE; 871 } 872 #else 873 auth_type = SECURITY_TYPE_NONE; 874 #endif 875 876 switch (client_ver) { 877 case CVERS_3_7: 878 case CVERS_3_8: 879 buf[0] = 1; 880 buf[1] = auth_type; 881 stream_write(cfd, buf, 2); 882 883 /* 2b. Read agreed security type */ 884 len = stream_read(cfd, buf, 1); 885 if (buf[0] != auth_type) { 886 /* deny */ 887 sres = htonl(1); 888 #ifdef __FreeBSD__ 889 message = "Auth failed: authentication type mismatch"; 890 #else 891 message = (unsigned char *) 892 "Auth failed: authentication type mismatch"; 893 #endif 894 goto report_and_done; 895 } 896 break; 897 case CVERS_3_3: 898 default: 899 be32enc(buf, auth_type); 900 stream_write(cfd, buf, 4); 901 break; 902 } 903 904 /* 2c. Do VNC authentication */ 905 switch (auth_type) { 906 case SECURITY_TYPE_NONE: 907 break; 908 case SECURITY_TYPE_VNC_AUTH: 909 /* 910 * The client encrypts the challenge with DES, using a password 911 * supplied by the user as the key. 912 * To form the key, the password is truncated to 913 * eight characters, or padded with null bytes on the right. 914 * The client then sends the resulting 16-bytes response. 915 */ 916 #ifndef NO_OPENSSL 917 #ifdef __FreeBSD__ 918 strncpy(keystr, rc->password, PASSWD_LENGTH); 919 #else 920 strncpy((char *)keystr, rc->password, PASSWD_LENGTH); 921 #endif 922 923 /* VNC clients encrypts the challenge with all the bit fields 924 * in each byte of the password mirrored. 925 * Here we flip each byte of the keystr. 926 */ 927 for (i = 0; i < PASSWD_LENGTH; i++) { 928 keystr[i] = (keystr[i] & 0xF0) >> 4 929 | (keystr[i] & 0x0F) << 4; 930 keystr[i] = (keystr[i] & 0xCC) >> 2 931 | (keystr[i] & 0x33) << 2; 932 keystr[i] = (keystr[i] & 0xAA) >> 1 933 | (keystr[i] & 0x55) << 1; 934 } 935 936 /* Initialize a 16-byte random challenge */ 937 arc4random_buf(challenge, sizeof(challenge)); 938 stream_write(cfd, challenge, AUTH_LENGTH); 939 940 /* Receive the 16-byte challenge response */ 941 stream_read(cfd, buf, AUTH_LENGTH); 942 943 memcpy(crypt_expected, challenge, AUTH_LENGTH); 944 945 /* Encrypt the Challenge with DES */ 946 DES_set_key((const_DES_cblock *)keystr, &ks); 947 DES_ecb_encrypt((const_DES_cblock *)challenge, 948 (const_DES_cblock *)crypt_expected, 949 &ks, DES_ENCRYPT); 950 DES_ecb_encrypt((const_DES_cblock *)(challenge + PASSWD_LENGTH), 951 (const_DES_cblock *)(crypt_expected + 952 PASSWD_LENGTH), 953 &ks, DES_ENCRYPT); 954 955 if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) { 956 #ifdef __FreeBSD__ 957 message = "Auth Failed: Invalid Password."; 958 #else 959 message = 960 (unsigned char *)"Auth Failed: Invalid Password."; 961 #endif 962 sres = htonl(1); 963 } else { 964 sres = 0; 965 } 966 #else 967 sres = htonl(1); 968 WPRINTF(("Auth not supported, no OpenSSL in your system")); 969 #endif 970 971 break; 972 } 973 974 switch (client_ver) { 975 case CVERS_3_7: 976 case CVERS_3_8: 977 report_and_done: 978 /* 2d. Write back a status */ 979 stream_write(cfd, &sres, 4); 980 981 if (sres) { 982 /* 3.7 does not want string explaining cause */ 983 if (client_ver == CVERS_3_8) { 984 #ifdef __FreeBSD__ 985 be32enc(buf, strlen(message)); 986 stream_write(cfd, buf, 4); 987 stream_write(cfd, message, strlen(message)); 988 #else 989 be32enc(buf, strlen((char *)message)); 990 stream_write(cfd, buf, 4); 991 stream_write(cfd, message, 992 strlen((char *)message)); 993 #endif 994 } 995 goto done; 996 } 997 break; 998 case CVERS_3_3: 999 default: 1000 /* for VNC auth case send status */ 1001 if (auth_type == SECURITY_TYPE_VNC_AUTH) { 1002 /* 2d. Write back a status */ 1003 stream_write(cfd, &sres, 4); 1004 } 1005 if (sres) { 1006 goto done; 1007 } 1008 break; 1009 } 1010 /* 3a. Read client shared-flag byte */ 1011 len = stream_read(cfd, buf, 1); 1012 1013 /* 4a. Write server-init info */ 1014 #ifndef __FreeBSD__ 1015 rfb_send_server_init_msg(cfd, rc); 1016 #else 1017 rfb_send_server_init_msg(cfd); 1018 #endif 1019 1020 if (!rc->zbuf) { 1021 rc->zbuf = malloc(RFB_ZLIB_BUFSZ + 16); 1022 assert(rc->zbuf != NULL); 1023 } 1024 1025 perror = pthread_create(&tid, NULL, rfb_wr_thr, rc); 1026 if (perror == 0) 1027 pthread_set_name_np(tid, "rfbout"); 1028 1029 /* Now read in client requests. 1st byte identifies type */ 1030 for (;;) { 1031 len = read(cfd, buf, 1); 1032 if (len <= 0) { 1033 DPRINTF(("rfb client exiting")); 1034 break; 1035 } 1036 1037 switch (buf[0]) { 1038 case CS_SET_PIXEL_FORMAT: 1039 rfb_recv_set_pixfmt_msg(rc, cfd); 1040 break; 1041 case CS_SET_ENCODINGS: 1042 rfb_recv_set_encodings_msg(rc, cfd); 1043 break; 1044 case CS_UPDATE_MSG: 1045 rfb_recv_update_msg(rc, cfd); 1046 break; 1047 case CS_KEY_EVENT: 1048 rfb_recv_key_msg(rc, cfd); 1049 break; 1050 case CS_POINTER_EVENT: 1051 rfb_recv_ptr_msg(rc, cfd); 1052 break; 1053 case CS_CUT_TEXT: 1054 rfb_recv_cuttext_msg(rc, cfd); 1055 break; 1056 default: 1057 WPRINTF(("rfb unknown cli-code %d!", buf[0] & 0xff)); 1058 goto done; 1059 } 1060 } 1061 done: 1062 rc->cfd = -1; 1063 if (perror == 0) 1064 pthread_join(tid, NULL); 1065 if (rc->enc_zlib_ok) 1066 deflateEnd(&rc->zstream); 1067 } 1068 1069 static void * 1070 rfb_thr(void *arg) 1071 { 1072 struct rfb_softc *rc; 1073 sigset_t set; 1074 1075 int cfd; 1076 1077 rc = arg; 1078 1079 sigemptyset(&set); 1080 sigaddset(&set, SIGPIPE); 1081 if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) { 1082 perror("pthread_sigmask"); 1083 return (NULL); 1084 } 1085 1086 for (;;) { 1087 rc->enc_raw_ok = false; 1088 rc->enc_zlib_ok = false; 1089 rc->enc_resize_ok = false; 1090 1091 cfd = accept(rc->sfd, NULL, NULL); 1092 if (rc->conn_wait) { 1093 pthread_mutex_lock(&rc->mtx); 1094 pthread_cond_signal(&rc->cond); 1095 pthread_mutex_unlock(&rc->mtx); 1096 rc->conn_wait = 0; 1097 } 1098 rfb_handle(rc, cfd); 1099 close(cfd); 1100 } 1101 1102 /* NOTREACHED */ 1103 return (NULL); 1104 } 1105 1106 static int 1107 sse42_supported(void) 1108 { 1109 u_int cpu_registers[4], ecx; 1110 1111 do_cpuid(1, cpu_registers); 1112 1113 ecx = cpu_registers[2]; 1114 1115 return ((ecx & CPUID2_SSE42) != 0); 1116 } 1117 1118 int 1119 #ifndef __FreeBSD__ 1120 rfb_init(char *hostname, int port, int wait, char *password, const char *name) 1121 #else 1122 rfb_init(char *hostname, int port, int wait, char *password) 1123 #endif 1124 { 1125 int e; 1126 char servname[6]; 1127 struct rfb_softc *rc; 1128 struct addrinfo *ai = NULL; 1129 struct addrinfo hints; 1130 int on = 1; 1131 int cnt; 1132 #ifndef WITHOUT_CAPSICUM 1133 cap_rights_t rights; 1134 #endif 1135 1136 rc = calloc(1, sizeof(struct rfb_softc)); 1137 1138 cnt = howmany(RFB_MAX_WIDTH, PIX_PER_CELL) * 1139 howmany(RFB_MAX_HEIGHT, PIX_PER_CELL); 1140 rc->crc = calloc(cnt, sizeof(uint32_t)); 1141 rc->crc_tmp = calloc(cnt, sizeof(uint32_t)); 1142 rc->crc_width = RFB_MAX_WIDTH; 1143 rc->crc_height = RFB_MAX_HEIGHT; 1144 rc->sfd = -1; 1145 1146 rc->password = password; 1147 1148 #ifndef __FreeBSD__ 1149 rc->name = name; 1150 #endif 1151 1152 snprintf(servname, sizeof(servname), "%d", port ? port : 5900); 1153 1154 if (!hostname || strlen(hostname) == 0) 1155 #if defined(INET) 1156 hostname = "127.0.0.1"; 1157 #elif defined(INET6) 1158 hostname = "[::1]"; 1159 #endif 1160 1161 memset(&hints, 0, sizeof(hints)); 1162 hints.ai_family = AF_UNSPEC; 1163 hints.ai_socktype = SOCK_STREAM; 1164 hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE; 1165 1166 if ((e = getaddrinfo(hostname, servname, &hints, &ai)) != 0) { 1167 EPRINTLN("getaddrinfo: %s", gai_strerror(e)); 1168 goto error; 1169 } 1170 1171 rc->sfd = socket(ai->ai_family, ai->ai_socktype, 0); 1172 if (rc->sfd < 0) { 1173 perror("socket"); 1174 goto error; 1175 } 1176 1177 setsockopt(rc->sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 1178 1179 if (bind(rc->sfd, ai->ai_addr, ai->ai_addrlen) < 0) { 1180 perror("bind"); 1181 goto error; 1182 } 1183 1184 if (listen(rc->sfd, 1) < 0) { 1185 perror("listen"); 1186 goto error; 1187 } 1188 1189 #ifndef WITHOUT_CAPSICUM 1190 cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE); 1191 if (caph_rights_limit(rc->sfd, &rights) == -1) 1192 errx(EX_OSERR, "Unable to apply rights for sandbox"); 1193 #endif 1194 1195 rc->hw_crc = sse42_supported(); 1196 1197 rc->conn_wait = wait; 1198 if (wait) { 1199 pthread_mutex_init(&rc->mtx, NULL); 1200 pthread_cond_init(&rc->cond, NULL); 1201 } 1202 1203 pthread_create(&rc->tid, NULL, rfb_thr, rc); 1204 pthread_set_name_np(rc->tid, "rfb"); 1205 1206 if (wait) { 1207 DPRINTF(("Waiting for rfb client...")); 1208 pthread_mutex_lock(&rc->mtx); 1209 pthread_cond_wait(&rc->cond, &rc->mtx); 1210 pthread_mutex_unlock(&rc->mtx); 1211 DPRINTF(("rfb client connected")); 1212 } 1213 1214 freeaddrinfo(ai); 1215 return (0); 1216 1217 error: 1218 if (ai != NULL) 1219 freeaddrinfo(ai); 1220 if (rc->sfd != -1) 1221 close(rc->sfd); 1222 free(rc->crc); 1223 free(rc->crc_tmp); 1224 free(rc); 1225 return (-1); 1226 } 1227 1228 #ifndef __FreeBSD__ 1229 int 1230 rfb_init_unix(const char *path, int wait, char *password, const char *name) 1231 { 1232 struct rfb_softc *rc; 1233 struct sockaddr_un sock; 1234 1235 if ((rc = calloc(1, sizeof (struct rfb_softc))) == NULL) { 1236 perror("calloc"); 1237 return (-1); 1238 } 1239 rc->sfd = -1; 1240 1241 if ((rc->crc = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32), 1242 sizeof (uint32_t))) == NULL) { 1243 perror("calloc"); 1244 goto fail; 1245 } 1246 if ((rc->crc_tmp = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32), 1247 sizeof (uint32_t))) == NULL) { 1248 perror("calloc"); 1249 goto fail; 1250 } 1251 rc->crc_width = RFB_MAX_WIDTH; 1252 rc->crc_height = RFB_MAX_HEIGHT; 1253 1254 rc->password = password; 1255 rc->name = name; 1256 1257 rc->sfd = socket(PF_UNIX, SOCK_STREAM, 0); 1258 if (rc->sfd < 0) { 1259 perror("socket"); 1260 goto fail; 1261 } 1262 1263 sock.sun_family = AF_UNIX; 1264 if (strlcpy(sock.sun_path, path, sizeof (sock.sun_path)) >= 1265 sizeof (sock.sun_path)) { 1266 (void) fprintf(stderr, "socket path '%s' too long\n", path); 1267 goto fail; 1268 } 1269 1270 (void) unlink(path); 1271 if (bind(rc->sfd, (struct sockaddr *)&sock, sizeof (sock)) < 0) { 1272 perror("bind"); 1273 goto fail; 1274 } 1275 1276 if (listen(rc->sfd, 1) < 0) { 1277 perror("listen"); 1278 goto fail; 1279 } 1280 1281 rc->hw_crc = sse42_supported(); 1282 1283 rc->conn_wait = wait; 1284 if (wait) { 1285 VERIFY3S(pthread_mutex_init(&rc->mtx, NULL), ==, 0); 1286 VERIFY3S(pthread_cond_init(&rc->cond, NULL), ==, 0); 1287 } 1288 1289 VERIFY3S(pthread_create(&rc->tid, NULL, rfb_thr, rc), ==, 0); 1290 pthread_set_name_np(rc->tid, "rfb"); 1291 1292 if (wait) { 1293 DPRINTF(("Waiting for rfb client...\n")); 1294 VERIFY3S(pthread_mutex_lock(&rc->mtx), ==, 0); 1295 VERIFY3S(pthread_cond_wait(&rc->cond, &rc->mtx), ==, 0); 1296 VERIFY3S(pthread_mutex_unlock(&rc->mtx), ==, 0); 1297 } 1298 1299 return (0); 1300 1301 fail: 1302 if (rc->sfd != -1) { 1303 VERIFY3S(close(rc->sfd), ==, 0); 1304 } 1305 free(rc->crc); 1306 free(rc->crc_tmp); 1307 free(rc); 1308 return (-1); 1309 } 1310 #endif 1311