xref: /freebsd/usr.sbin/bhyve/rfb.c (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
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