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