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