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