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