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