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
78static 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
106struct 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
144struct 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
158struct rfb_srvr_info {
159	uint16_t		width;
160	uint16_t		height;
161	struct rfb_pixfmt	pixfmt;
162	uint32_t		namelen;
163};
164
165struct 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
185struct rfb_enc_msg {
186	uint8_t		type;
187	uint8_t		pad;
188	uint16_t	numencs;
189};
190
191struct 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
200struct rfb_key_msg {
201	uint8_t		type;
202	uint8_t		down;
203	uint16_t	pad;
204	uint32_t	sym;
205};
206
207struct rfb_client_msg {
208	uint8_t		type;
209	uint8_t		subtype;
210};
211
212struct 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
220struct rfb_ptr_msg {
221	uint8_t		type;
222	uint8_t		button;
223	uint16_t	x;
224	uint16_t	y;
225};
226
227struct rfb_srvr_updt_msg {
228	uint8_t		type;
229	uint8_t		pad;
230	uint16_t	numrects;
231};
232
233struct 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
241struct rfb_cuttext_msg {
242	uint8_t		type;
243	uint8_t		padding[3];
244	uint32_t	length;
245};
246
247static void
248rfb_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
275static void
276rfb_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
296static void
297rfb_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
317static void
318rfb_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
326static void
327rfb_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 */
360static __inline uint32_t
361fast_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
378static int
379rfb_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
391static int
392rfb_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
450doraw:
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
472static int
473rfb_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
532doraw:
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
549static int
550rfb_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
716done:
717	rc->sending = false;
718
719	return (retval);
720}
721
722
723static void
724rfb_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
740static void
741rfb_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
751static void
752rfb_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
768static void
769rfb_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
779static void
780rfb_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
795static int64_t
796timeval_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
804static void *
805rfb_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
856static void
857rfb_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:
998report_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	}
1074done:
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
1082static void *
1083rfb_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
1122static int
1123sse42_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
1134int
1135rfb_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