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