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