]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/rfb.c
lua: Update to 5.4.4
[FreeBSD/FreeBSD.git] / usr.sbin / bhyve / rfb.c
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, (uint8_t *)&pixfmt_msg + 1,
326             sizeof(pixfmt_msg) - 1);
327 }
328
329 static void
330 rfb_recv_set_encodings_msg(struct rfb_softc *rc, int cfd)
331 {
332         struct rfb_enc_msg enc_msg;
333         int i;
334         uint32_t encoding;
335
336         (void)stream_read(cfd, (uint8_t *)&enc_msg + 1, sizeof(enc_msg) - 1);
337
338         for (i = 0; i < htons(enc_msg.numencs); i++) {
339                 (void)stream_read(cfd, &encoding, sizeof(encoding));
340                 switch (htonl(encoding)) {
341                 case RFB_ENCODING_RAW:
342                         rc->enc_raw_ok = true;
343                         break;
344                 case RFB_ENCODING_ZLIB:
345                         if (!rc->enc_zlib_ok) {
346                                 deflateInit(&rc->zstream, Z_BEST_SPEED);
347                                 rc->enc_zlib_ok = true;
348                         }
349                         break;
350                 case RFB_ENCODING_RESIZE:
351                         rc->enc_resize_ok = true;
352                         break;
353                 case RFB_ENCODING_EXT_KEYEVENT:
354                         rc->enc_extkeyevent_ok = true;
355                         break;
356                 }
357         }
358 }
359
360 /*
361  * Calculate CRC32 using SSE4.2; Intel or AMD Bulldozer+ CPUs only
362  */
363 static __inline uint32_t
364 fast_crc32(void *buf, int len, uint32_t crcval)
365 {
366         uint32_t q = len / sizeof(uint32_t);
367         uint32_t *p = (uint32_t *)buf;
368
369         while (q--) {
370                 asm volatile (
371                         ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
372                         :"=S" (crcval)
373                         :"0" (crcval), "c" (*p)
374                 );
375                 p++;
376         }
377
378         return (crcval);
379 }
380
381 static int
382 rfb_send_update_header(struct rfb_softc *rc __unused, int cfd, int numrects)
383 {
384         struct rfb_srvr_updt_msg supdt_msg;
385
386         supdt_msg.type = 0;
387         supdt_msg.pad = 0;
388         supdt_msg.numrects = htons(numrects);
389
390         return stream_write(cfd, &supdt_msg,
391             sizeof(struct rfb_srvr_updt_msg));
392 }
393
394 static int
395 rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc,
396               int x, int y, int w, int h)
397 {
398         struct rfb_srvr_rect_hdr srect_hdr;
399         unsigned long zlen;
400         ssize_t nwrite, total;
401         int err;
402         uint32_t *p;
403         uint8_t *zbufp;
404
405         /*
406          * Send a single rectangle of the given x, y, w h dimensions.
407          */
408
409         /* Rectangle header */
410         srect_hdr.x = htons(x);
411         srect_hdr.y = htons(y);
412         srect_hdr.width = htons(w);
413         srect_hdr.height = htons(h);
414
415         h = y + h;
416         w *= sizeof(uint32_t);
417         if (rc->enc_zlib_ok) {
418                 zbufp = rc->zbuf;
419                 rc->zstream.total_in = 0;
420                 rc->zstream.total_out = 0;
421                 for (p = &gc->data[y * gc->width + x]; y < h; y++) {
422                         rc->zstream.next_in = (Bytef *)p;
423                         rc->zstream.avail_in = w;
424                         rc->zstream.next_out = (Bytef *)zbufp;
425                         rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16 -
426                                                 rc->zstream.total_out;
427                         rc->zstream.data_type = Z_BINARY;
428
429                         /* Compress with zlib */
430                         err = deflate(&rc->zstream, Z_SYNC_FLUSH);
431                         if (err != Z_OK) {
432                                 WPRINTF(("zlib[rect] deflate err: %d", err));
433                                 rc->enc_zlib_ok = false;
434                                 deflateEnd(&rc->zstream);
435                                 goto doraw;
436                         }
437                         zbufp = rc->zbuf + rc->zstream.total_out;
438                         p += gc->width;
439                 }
440                 srect_hdr.encoding = htonl(RFB_ENCODING_ZLIB);
441                 nwrite = stream_write(cfd, &srect_hdr,
442                                       sizeof(struct rfb_srvr_rect_hdr));
443                 if (nwrite <= 0)
444                         return (nwrite);
445
446                 zlen = htonl(rc->zstream.total_out);
447                 nwrite = stream_write(cfd, &zlen, sizeof(uint32_t));
448                 if (nwrite <= 0)
449                         return (nwrite);
450                 return (stream_write(cfd, rc->zbuf, rc->zstream.total_out));
451         }
452
453 doraw:
454
455         total = 0;
456         zbufp = rc->zbuf;
457         for (p = &gc->data[y * gc->width + x]; y < h; y++) {
458                 memcpy(zbufp, p, w);
459                 zbufp += w;
460                 total += w;
461                 p += gc->width;
462         }
463
464         srect_hdr.encoding = htonl(RFB_ENCODING_RAW);
465         nwrite = stream_write(cfd, &srect_hdr,
466                               sizeof(struct rfb_srvr_rect_hdr));
467         if (nwrite <= 0)
468                 return (nwrite);
469
470         total = stream_write(cfd, rc->zbuf, total);
471
472         return (total);
473 }
474
475 static int
476 rfb_send_all(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc)
477 {
478         struct rfb_srvr_updt_msg supdt_msg;
479         struct rfb_srvr_rect_hdr srect_hdr;
480         ssize_t nwrite;
481         unsigned long zlen;
482         int err;
483
484         /*
485          * Send the whole thing
486          */
487
488         /* Number of rectangles: 1 */
489         supdt_msg.type = 0;
490         supdt_msg.pad = 0;
491         supdt_msg.numrects = htons(1);
492         nwrite = stream_write(cfd, &supdt_msg,
493                               sizeof(struct rfb_srvr_updt_msg));
494         if (nwrite <= 0)
495                 return (nwrite);
496
497         /* Rectangle header */
498         srect_hdr.x = 0;
499         srect_hdr.y = 0;
500         srect_hdr.width = htons(gc->width);
501         srect_hdr.height = htons(gc->height);
502         if (rc->enc_zlib_ok) {
503                 rc->zstream.next_in = (Bytef *)gc->data;
504                 rc->zstream.avail_in = gc->width * gc->height *
505                                    sizeof(uint32_t);
506                 rc->zstream.next_out = (Bytef *)rc->zbuf;
507                 rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16;
508                 rc->zstream.data_type = Z_BINARY;
509
510                 rc->zstream.total_in = 0;
511                 rc->zstream.total_out = 0;
512
513                 /* Compress with zlib */
514                 err = deflate(&rc->zstream, Z_SYNC_FLUSH);
515                 if (err != Z_OK) {
516                         WPRINTF(("zlib deflate err: %d", err));
517                         rc->enc_zlib_ok = false;
518                         deflateEnd(&rc->zstream);
519                         goto doraw;
520                 }
521
522                 srect_hdr.encoding = htonl(RFB_ENCODING_ZLIB);
523                 nwrite = stream_write(cfd, &srect_hdr,
524                                       sizeof(struct rfb_srvr_rect_hdr));
525                 if (nwrite <= 0)
526                         return (nwrite);
527
528                 zlen = htonl(rc->zstream.total_out);
529                 nwrite = stream_write(cfd, &zlen, sizeof(uint32_t));
530                 if (nwrite <= 0)
531                         return (nwrite);
532                 return (stream_write(cfd, rc->zbuf, rc->zstream.total_out));
533         }
534
535 doraw:
536         srect_hdr.encoding = htonl(RFB_ENCODING_RAW);
537         nwrite = stream_write(cfd, &srect_hdr,
538                               sizeof(struct rfb_srvr_rect_hdr));
539         if (nwrite <= 0)
540                 return (nwrite);
541
542         nwrite = stream_write(cfd, gc->data,
543                        gc->width * gc->height * sizeof(uint32_t));
544
545         return (nwrite);
546 }
547
548 #define PIX_PER_CELL    32
549 #define PIXCELL_SHIFT   5
550 #define PIXCELL_MASK    0x1F
551
552 static int
553 rfb_send_screen(struct rfb_softc *rc, int cfd)
554 {
555         struct bhyvegc_image *gc_image;
556         ssize_t nwrite;
557         int x, y;
558         int celly, cellwidth;
559         int xcells, ycells;
560         int w, h;
561         uint32_t *p;
562         int rem_x, rem_y;   /* remainder for resolutions not x32 pixels ratio */
563         int retval;
564         uint32_t *crc_p, *orig_crc;
565         int changes;
566         bool expected;
567
568         /* Return if another thread sending */
569         expected = false;
570         if (atomic_compare_exchange_strong(&rc->sending, &expected, true) == false)
571                 return (1);
572
573         retval = 1;
574
575         /* Updates require a preceding update request */
576         if (atomic_exchange(&rc->pending, false) == false)
577                 goto done;
578
579         console_refresh();
580         gc_image = console_get_image();
581
582         /* Clear old CRC values when the size changes */
583         if (rc->crc_width != gc_image->width ||
584             rc->crc_height != gc_image->height) {
585                 memset(rc->crc, 0, sizeof(uint32_t) *
586                     howmany(RFB_MAX_WIDTH, PIX_PER_CELL) *
587                     howmany(RFB_MAX_HEIGHT, PIX_PER_CELL));
588                 rc->crc_width = gc_image->width;
589                 rc->crc_height = gc_image->height;
590         }
591
592        /* A size update counts as an update in itself */
593        if (rc->width != gc_image->width ||
594            rc->height != gc_image->height) {
595                rc->width = gc_image->width;
596                rc->height = gc_image->height;
597                if (rc->enc_resize_ok) {
598                        rfb_send_resize_update_msg(rc, cfd);
599                        rc->update_all = true;
600                        goto done;
601                }
602        }
603
604        if (atomic_exchange(&rc->update_all, false) == true) {
605                retval = rfb_send_all(rc, cfd, gc_image);
606                goto done;
607        }
608
609         /*
610          * Calculate the checksum for each 32x32 cell. Send each that
611          * has changed since the last scan.
612          */
613
614         w = rc->crc_width;
615         h = rc->crc_height;
616         xcells = howmany(rc->crc_width, PIX_PER_CELL);
617         ycells = howmany(rc->crc_height, PIX_PER_CELL);
618
619         rem_x = w & PIXCELL_MASK;
620
621         rem_y = h & PIXCELL_MASK;
622         if (!rem_y)
623                 rem_y = PIX_PER_CELL;
624
625         p = gc_image->data;
626
627         /*
628          * Go through all cells and calculate crc. If significant number
629          * of changes, then send entire screen.
630          * crc_tmp is dual purpose: to store the new crc and to flag as
631          * a cell that has changed.
632          */
633         crc_p = rc->crc_tmp - xcells;
634         orig_crc = rc->crc - xcells;
635         changes = 0;
636         memset(rc->crc_tmp, 0, sizeof(uint32_t) * xcells * ycells);
637         for (y = 0; y < h; y++) {
638                 if ((y & PIXCELL_MASK) == 0) {
639                         crc_p += xcells;
640                         orig_crc += xcells;
641                 }
642
643                 for (x = 0; x < xcells; x++) {
644                         if (x == (xcells - 1) && rem_x > 0)
645                                 cellwidth = rem_x;
646                         else
647                                 cellwidth = PIX_PER_CELL;
648
649                         if (rc->hw_crc)
650                                 crc_p[x] = fast_crc32(p,
651                                              cellwidth * sizeof(uint32_t),
652                                              crc_p[x]);
653                         else
654                                 crc_p[x] = (uint32_t)crc32(crc_p[x],
655                                              (Bytef *)p,
656                                              cellwidth * sizeof(uint32_t));
657
658                         p += cellwidth;
659
660                         /* check for crc delta if last row in cell */
661                         if ((y & PIXCELL_MASK) == PIXCELL_MASK || y == (h-1)) {
662                                 if (orig_crc[x] != crc_p[x]) {
663                                         orig_crc[x] = crc_p[x];
664                                         crc_p[x] = 1;
665                                         changes++;
666                                 } else {
667                                         crc_p[x] = 0;
668                                 }
669                         }
670                 }
671         }
672
673        /*
674         * We only send the update if there are changes.
675         * Restore the pending flag since it was unconditionally cleared
676         * above.
677         */
678         if (!changes) {
679                 rc->pending = true;
680                 goto done;
681         }
682
683         /* If number of changes is > THRESH percent, send the whole screen */
684         if (((changes * 100) / (xcells * ycells)) >= RFB_SEND_ALL_THRESH) {
685                 retval = rfb_send_all(rc, cfd, gc_image);
686                 goto done;
687         }
688
689         rfb_send_update_header(rc, cfd, changes);
690
691         /* Go through all cells, and send only changed ones */
692         crc_p = rc->crc_tmp;
693         for (y = 0; y < h; y += PIX_PER_CELL) {
694                 /* previous cell's row */
695                 celly = (y >> PIXCELL_SHIFT);
696
697                 /* Delta check crc to previous set */
698                 for (x = 0; x < xcells; x++) {
699                         if (*crc_p++ == 0)
700                                 continue;
701
702                         if (x == (xcells - 1) && rem_x > 0)
703                                 cellwidth = rem_x;
704                         else
705                                 cellwidth = PIX_PER_CELL;
706                         nwrite = rfb_send_rect(rc, cfd,
707                                 gc_image,
708                                 x * PIX_PER_CELL,
709                                 celly * PIX_PER_CELL,
710                                 cellwidth,
711                                 y + PIX_PER_CELL >= h ? rem_y : PIX_PER_CELL);
712                         if (nwrite <= 0) {
713                                 retval = nwrite;
714                                 goto done;
715                         }
716                 }
717         }
718
719 done:
720         rc->sending = false;
721
722         return (retval);
723 }
724
725
726 static void
727 rfb_recv_update_msg(struct rfb_softc *rc, int cfd)
728 {
729         struct rfb_updt_msg updt_msg;
730
731         (void)stream_read(cfd, (uint8_t *)&updt_msg + 1 , sizeof(updt_msg) - 1);
732
733         if (rc->enc_extkeyevent_ok && (!rc->enc_extkeyevent_send)) {
734                 rfb_send_extended_keyevent_update_msg(rc, cfd);
735                 rc->enc_extkeyevent_send = true;
736         }
737
738         rc->pending = true;
739         if (!updt_msg.incremental)
740                 rc->update_all = true;
741 }
742
743 static void
744 rfb_recv_key_msg(struct rfb_softc *rc, int cfd)
745 {
746         struct rfb_key_msg key_msg;
747
748         (void)stream_read(cfd, (uint8_t *)&key_msg + 1, sizeof(key_msg) - 1);
749
750         console_key_event(key_msg.down, htonl(key_msg.sym), htonl(0));
751         rc->input_detected = true;
752 }
753
754 static void
755 rfb_recv_client_msg(struct rfb_softc *rc, int cfd)
756 {
757         struct rfb_client_msg client_msg;
758         struct rfb_extended_key_msg extkey_msg;
759
760         (void)stream_read(cfd, (uint8_t *)&client_msg + 1,
761             sizeof(client_msg) - 1);
762
763         if (client_msg.subtype == RFB_CLIENTMSG_EXT_KEYEVENT) {
764                 (void)stream_read(cfd, (uint8_t *)&extkey_msg + 2,
765                     sizeof(extkey_msg) - 2);
766                 console_key_event((int)extkey_msg.down, htonl(extkey_msg.sym), htonl(extkey_msg.code));
767                 rc->input_detected = true;
768         }
769 }
770
771 static void
772 rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd)
773 {
774         struct rfb_ptr_msg ptr_msg;
775
776         (void)stream_read(cfd, (uint8_t *)&ptr_msg + 1, sizeof(ptr_msg) - 1);
777
778         console_ptr_event(ptr_msg.button, htons(ptr_msg.x), htons(ptr_msg.y));
779         rc->input_detected = true;
780 }
781
782 static void
783 rfb_recv_cuttext_msg(struct rfb_softc *rc __unused, int cfd)
784 {
785         struct rfb_cuttext_msg ct_msg;
786         unsigned char buf[32];
787         int len;
788
789         len = stream_read(cfd, (uint8_t *)&ct_msg + 1, sizeof(ct_msg) - 1);
790         ct_msg.length = htonl(ct_msg.length);
791         while (ct_msg.length > 0) {
792                 len = stream_read(cfd, buf, ct_msg.length > sizeof(buf) ?
793                         sizeof(buf) : ct_msg.length);
794                 ct_msg.length -= len;
795         }
796 }
797
798 static int64_t
799 timeval_delta(struct timeval *prev, struct timeval *now)
800 {
801         int64_t n1, n2;
802         n1 = now->tv_sec * 1000000 + now->tv_usec;
803         n2 = prev->tv_sec * 1000000 + prev->tv_usec;
804         return (n1 - n2);
805 }
806
807 static void *
808 rfb_wr_thr(void *arg)
809 {
810         struct rfb_softc *rc;
811         fd_set rfds;
812         struct timeval tv;
813         struct timeval prev_tv;
814         int64_t tdiff;
815         int cfd;
816         int err;
817
818         rc = arg;
819         cfd = rc->cfd;
820
821         prev_tv.tv_sec = 0;
822         prev_tv.tv_usec = 0;
823         while (rc->cfd >= 0) {
824                 FD_ZERO(&rfds);
825                 FD_SET(cfd, &rfds);
826                 tv.tv_sec = 0;
827                 tv.tv_usec = CFD_SEL_DELAY;
828
829                 err = select(cfd+1, &rfds, NULL, NULL, &tv);
830                 if (err < 0)
831                         return (NULL);
832
833                 /* Determine if its time to push screen; ~24hz */
834                 gettimeofday(&tv, NULL);
835                 tdiff = timeval_delta(&prev_tv, &tv);
836                 if (tdiff >= SCREEN_POLL_DELAY) {
837                         bool input;
838                         prev_tv.tv_sec = tv.tv_sec;
839                         prev_tv.tv_usec = tv.tv_usec;
840                         input = atomic_exchange(&rc->input_detected, false);
841                         /*
842                          * Refresh the screen on every second trip through the loop,
843                          * or if keyboard/mouse input has been detected.
844                          */
845                         if ((++rc->wrcount & 1) || input) {
846                                 if (rfb_send_screen(rc, cfd) <= 0) {
847                                         return (NULL);
848                                 }
849                         }
850                 } else {
851                         /* sleep */
852                         usleep(SCREEN_POLL_DELAY - tdiff);
853                 }
854         }
855
856         return (NULL);
857 }
858
859 static void
860 rfb_handle(struct rfb_softc *rc, int cfd)
861 {
862         const char *vbuf = "RFB 003.008\n";
863         unsigned char buf[80];
864         unsigned const char *message;
865
866 #ifndef NO_OPENSSL
867         unsigned char challenge[AUTH_LENGTH];
868         unsigned char keystr[PASSWD_LENGTH];
869         unsigned char crypt_expected[AUTH_LENGTH];
870
871         DES_key_schedule ks;
872         int i;
873 #endif
874         uint8_t client_ver;
875         uint8_t auth_type;
876         pthread_t tid;
877         uint32_t sres = 0;
878         int len;
879         int perror = 1;
880
881         rc->cfd = cfd;
882
883         /* 1a. Send server version */
884         stream_write(cfd, vbuf, strlen(vbuf));
885
886         /* 1b. Read client version */
887         len = stream_read(cfd, buf, VERSION_LENGTH);
888         if (len != VERSION_LENGTH ||
889             strncmp(vbuf, buf, VERSION_LENGTH - 2) != 0) {
890                 goto done;
891         }
892
893         client_ver = buf[VERSION_LENGTH - 2];
894         if (client_ver != CVERS_3_8 && client_ver != CVERS_3_7) {
895                 /* only recognize 3.3, 3.7 & 3.8. Others dflt to 3.3 */
896                 client_ver = CVERS_3_3;
897         }
898
899         /* 2a. Send security type */
900         buf[0] = 1;
901
902         /* In versions 3.7 & 3.8, it's 2-way handshake */
903         /* For version 3.3, server says what the authentication type must be */
904 #ifndef NO_OPENSSL
905         if (rc->password) {
906                 auth_type = SECURITY_TYPE_VNC_AUTH;
907         } else {
908                 auth_type = SECURITY_TYPE_NONE;
909         }
910 #else
911         auth_type = SECURITY_TYPE_NONE;
912 #endif
913
914         switch (client_ver) {
915         case CVERS_3_7:
916         case CVERS_3_8:
917                 buf[0] = 1;
918                 buf[1] = auth_type;
919                 stream_write(cfd, buf, 2);
920
921                 /* 2b. Read agreed security type */
922                 len = stream_read(cfd, buf, 1);
923                 if (buf[0] != auth_type) {
924                         /* deny */
925                         sres = htonl(1);
926                         message = "Auth failed: authentication type mismatch";
927                         goto report_and_done;
928                 }
929                 break;
930         case CVERS_3_3:
931         default:
932                 be32enc(buf, auth_type);
933                 stream_write(cfd, buf, 4);
934                 break;
935         }
936
937         /* 2c. Do VNC authentication */
938         switch (auth_type) {
939         case SECURITY_TYPE_NONE:
940                 break;
941         case SECURITY_TYPE_VNC_AUTH:
942                 /*
943                  * The client encrypts the challenge with DES, using a password
944                  * supplied by the user as the key.
945                  * To form the key, the password is truncated to
946                  * eight characters, or padded with null bytes on the right.
947                  * The client then sends the resulting 16-bytes response.
948                  */
949 #ifndef NO_OPENSSL
950                 strncpy(keystr, rc->password, PASSWD_LENGTH);
951
952                 /* VNC clients encrypts the challenge with all the bit fields
953                  * in each byte of the password mirrored.
954                  * Here we flip each byte of the keystr.
955                  */
956                 for (i = 0; i < PASSWD_LENGTH; i++) {
957                         keystr[i] = (keystr[i] & 0xF0) >> 4
958                                   | (keystr[i] & 0x0F) << 4;
959                         keystr[i] = (keystr[i] & 0xCC) >> 2
960                                   | (keystr[i] & 0x33) << 2;
961                         keystr[i] = (keystr[i] & 0xAA) >> 1
962                                   | (keystr[i] & 0x55) << 1;
963                 }
964
965                 /* Initialize a 16-byte random challenge */
966                 arc4random_buf(challenge, sizeof(challenge));
967                 stream_write(cfd, challenge, AUTH_LENGTH);
968
969                 /* Receive the 16-byte challenge response */
970                 stream_read(cfd, buf, AUTH_LENGTH);
971
972                 memcpy(crypt_expected, challenge, AUTH_LENGTH);
973
974                 /* Encrypt the Challenge with DES */
975                 DES_set_key((const_DES_cblock *)keystr, &ks);
976                 DES_ecb_encrypt((const_DES_cblock *)challenge,
977                                 (const_DES_cblock *)crypt_expected,
978                                 &ks, DES_ENCRYPT);
979                 DES_ecb_encrypt((const_DES_cblock *)(challenge + PASSWD_LENGTH),
980                                 (const_DES_cblock *)(crypt_expected +
981                                 PASSWD_LENGTH),
982                                 &ks, DES_ENCRYPT);
983
984                 if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) {
985                         message = "Auth Failed: Invalid Password.";
986                         sres = htonl(1);
987                 } else {
988                         sres = 0;
989                 }
990 #else
991                 sres = htonl(1);
992                 WPRINTF(("Auth not supported, no OpenSSL in your system"));
993 #endif
994
995                 break;
996         }
997
998         switch (client_ver) {
999         case CVERS_3_7:
1000         case CVERS_3_8:
1001 report_and_done:
1002                 /* 2d. Write back a status */
1003                 stream_write(cfd, &sres, 4);
1004
1005                 if (sres) {
1006                         /* 3.7 does not want string explaining cause */
1007                         if (client_ver == CVERS_3_8) {
1008                                 be32enc(buf, strlen(message));
1009                                 stream_write(cfd, buf, 4);
1010                                 stream_write(cfd, message, strlen(message));
1011                         }
1012                         goto done;
1013                 }
1014                 break;
1015         case CVERS_3_3:
1016         default:
1017                 /* for VNC auth case send status */
1018                 if (auth_type == SECURITY_TYPE_VNC_AUTH) {
1019                         /* 2d. Write back a status */
1020                         stream_write(cfd, &sres, 4);
1021                 }
1022                 if (sres) {
1023                         goto done;
1024                 }
1025                 break;
1026         }
1027         /* 3a. Read client shared-flag byte */
1028         len = stream_read(cfd, buf, 1);
1029
1030         /* 4a. Write server-init info */
1031         rfb_send_server_init_msg(cfd);
1032
1033         if (!rc->zbuf) {
1034                 rc->zbuf = malloc(RFB_ZLIB_BUFSZ + 16);
1035                 assert(rc->zbuf != NULL);
1036         }
1037
1038         perror = pthread_create(&tid, NULL, rfb_wr_thr, rc);
1039         if (perror == 0)
1040                 pthread_set_name_np(tid, "rfbout");
1041
1042         /* Now read in client requests. 1st byte identifies type */
1043         for (;;) {
1044                 len = read(cfd, buf, 1);
1045                 if (len <= 0) {
1046                         DPRINTF(("rfb client exiting"));
1047                         break;
1048                 }
1049
1050                 switch (buf[0]) {
1051                 case CS_SET_PIXEL_FORMAT:
1052                         rfb_recv_set_pixfmt_msg(rc, cfd);
1053                         break;
1054                 case CS_SET_ENCODINGS:
1055                         rfb_recv_set_encodings_msg(rc, cfd);
1056                         break;
1057                 case CS_UPDATE_MSG:
1058                         rfb_recv_update_msg(rc, cfd);
1059                         break;
1060                 case CS_KEY_EVENT:
1061                         rfb_recv_key_msg(rc, cfd);
1062                         break;
1063                 case CS_POINTER_EVENT:
1064                         rfb_recv_ptr_msg(rc, cfd);
1065                         break;
1066                 case CS_CUT_TEXT:
1067                         rfb_recv_cuttext_msg(rc, cfd);
1068                         break;
1069                 case CS_MSG_CLIENT_QEMU:
1070                         rfb_recv_client_msg(rc, cfd);
1071                         break;
1072                 default:
1073                         WPRINTF(("rfb unknown cli-code %d!", buf[0] & 0xff));
1074                         goto done;
1075                 }
1076         }
1077 done:
1078         rc->cfd = -1;
1079         if (perror == 0)
1080                 pthread_join(tid, NULL);
1081         if (rc->enc_zlib_ok)
1082                 deflateEnd(&rc->zstream);
1083 }
1084
1085 static void *
1086 rfb_thr(void *arg)
1087 {
1088         struct rfb_softc *rc;
1089         sigset_t set;
1090
1091         int cfd;
1092
1093         rc = arg;
1094
1095         sigemptyset(&set);
1096         sigaddset(&set, SIGPIPE);
1097         if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) {
1098                 perror("pthread_sigmask");
1099                 return (NULL);
1100         }
1101
1102         for (;;) {
1103                 rc->enc_raw_ok = false;
1104                 rc->enc_zlib_ok = false;
1105                 rc->enc_resize_ok = false;
1106                 rc->enc_extkeyevent_ok = false;
1107
1108                 rc->enc_extkeyevent_send = false;
1109
1110                 cfd = accept(rc->sfd, NULL, NULL);
1111                 if (rc->conn_wait) {
1112                         pthread_mutex_lock(&rc->mtx);
1113                         pthread_cond_signal(&rc->cond);
1114                         pthread_mutex_unlock(&rc->mtx);
1115                         rc->conn_wait = 0;
1116                 }
1117                 rfb_handle(rc, cfd);
1118                 close(cfd);
1119         }
1120
1121         /* NOTREACHED */
1122         return (NULL);
1123 }
1124
1125 static int
1126 sse42_supported(void)
1127 {
1128         u_int cpu_registers[4], ecx;
1129
1130         do_cpuid(1, cpu_registers);
1131
1132         ecx = cpu_registers[2];
1133
1134         return ((ecx & CPUID2_SSE42) != 0);
1135 }
1136
1137 int
1138 rfb_init(const char *hostname, int port, int wait, const char *password)
1139 {
1140         int e;
1141         char servname[6];
1142         struct rfb_softc *rc;
1143         struct addrinfo *ai = NULL;
1144         struct addrinfo hints;
1145         int on = 1;
1146         int cnt;
1147 #ifndef WITHOUT_CAPSICUM
1148         cap_rights_t rights;
1149 #endif
1150
1151         rc = calloc(1, sizeof(struct rfb_softc));
1152
1153         cnt = howmany(RFB_MAX_WIDTH, PIX_PER_CELL) *
1154             howmany(RFB_MAX_HEIGHT, PIX_PER_CELL);
1155         rc->crc = calloc(cnt, sizeof(uint32_t));
1156         rc->crc_tmp = calloc(cnt, sizeof(uint32_t));
1157         rc->crc_width = RFB_MAX_WIDTH;
1158         rc->crc_height = RFB_MAX_HEIGHT;
1159         rc->sfd = -1;
1160
1161         rc->password = password;
1162
1163         snprintf(servname, sizeof(servname), "%d", port ? port : 5900);
1164
1165         if (!hostname || strlen(hostname) == 0)
1166 #if defined(INET)
1167                 hostname = "127.0.0.1";
1168 #elif defined(INET6)
1169                 hostname = "[::1]";
1170 #endif
1171
1172         memset(&hints, 0, sizeof(hints));
1173         hints.ai_family = AF_UNSPEC;
1174         hints.ai_socktype = SOCK_STREAM;
1175         hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE;
1176
1177         if ((e = getaddrinfo(hostname, servname, &hints, &ai)) != 0) {
1178                 EPRINTLN("getaddrinfo: %s", gai_strerror(e));
1179                 goto error;
1180         }
1181
1182         rc->sfd = socket(ai->ai_family, ai->ai_socktype, 0);
1183         if (rc->sfd < 0) {
1184                 perror("socket");
1185                 goto error;
1186         }
1187
1188         setsockopt(rc->sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1189
1190         if (bind(rc->sfd, ai->ai_addr, ai->ai_addrlen) < 0) {
1191                 perror("bind");
1192                 goto error;
1193         }
1194
1195         if (listen(rc->sfd, 1) < 0) {
1196                 perror("listen");
1197                 goto error;
1198         }
1199
1200 #ifndef WITHOUT_CAPSICUM
1201         cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE);
1202         if (caph_rights_limit(rc->sfd, &rights) == -1)
1203                 errx(EX_OSERR, "Unable to apply rights for sandbox");
1204 #endif
1205
1206         rc->hw_crc = sse42_supported();
1207
1208         rc->conn_wait = wait;
1209         if (wait) {
1210                 pthread_mutex_init(&rc->mtx, NULL);
1211                 pthread_cond_init(&rc->cond, NULL);
1212         }
1213
1214         pthread_create(&rc->tid, NULL, rfb_thr, rc);
1215         pthread_set_name_np(rc->tid, "rfb");
1216
1217         if (wait) {
1218                 DPRINTF(("Waiting for rfb client..."));
1219                 pthread_mutex_lock(&rc->mtx);
1220                 pthread_cond_wait(&rc->cond, &rc->mtx);
1221                 pthread_mutex_unlock(&rc->mtx);
1222                 DPRINTF(("rfb client connected"));
1223         }
1224
1225         freeaddrinfo(ai);
1226         return (0);
1227
1228  error:
1229         if (ai != NULL)
1230                 freeaddrinfo(ai);
1231         if (rc->sfd != -1)
1232                 close(rc->sfd);
1233         free(rc->crc);
1234         free(rc->crc_tmp);
1235         free(rc);
1236         return (-1);
1237 }