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