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