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