]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bhyve/rfb.c
amd64: stop using top of the thread' kernel stack for FPU user save area
[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         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, int cfd)
322 {
323         struct rfb_pixfmt_msg pixfmt_msg;
324
325         (void)stream_read(cfd, ((void *)&pixfmt_msg)+1, sizeof(pixfmt_msg)-1);
326 }
327
328
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, ((void *)&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, 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, ((void *)&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, ((void *)&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, ((void *)&client_msg) + 1, sizeof(client_msg) - 1);
761
762         if (client_msg.subtype == RFB_CLIENTMSG_EXT_KEYEVENT ) {
763                 (void)stream_read(cfd, ((void *)&extkey_msg) + 2, sizeof(extkey_msg) - 2);
764                 console_key_event((int)extkey_msg.down, htonl(extkey_msg.sym), htonl(extkey_msg.code));
765                 rc->input_detected = true;
766         }
767 }
768
769 static void
770 rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd)
771 {
772         struct rfb_ptr_msg ptr_msg;
773
774         (void)stream_read(cfd, ((void *)&ptr_msg) + 1, sizeof(ptr_msg) - 1);
775
776         console_ptr_event(ptr_msg.button, htons(ptr_msg.x), htons(ptr_msg.y));
777         rc->input_detected = true;
778 }
779
780 static void
781 rfb_recv_cuttext_msg(struct rfb_softc *rc, int cfd)
782 {
783         struct rfb_cuttext_msg ct_msg;
784         unsigned char buf[32];
785         int len;
786
787         len = stream_read(cfd, ((void *)&ct_msg) + 1, sizeof(ct_msg) - 1);
788         ct_msg.length = htonl(ct_msg.length);
789         while (ct_msg.length > 0) {
790                 len = stream_read(cfd, buf, ct_msg.length > sizeof(buf) ?
791                         sizeof(buf) : ct_msg.length);
792                 ct_msg.length -= len;
793         }
794 }
795
796 static int64_t
797 timeval_delta(struct timeval *prev, struct timeval *now)
798 {
799         int64_t n1, n2;
800         n1 = now->tv_sec * 1000000 + now->tv_usec;
801         n2 = prev->tv_sec * 1000000 + prev->tv_usec;
802         return (n1 - n2);
803 }
804
805 static void *
806 rfb_wr_thr(void *arg)
807 {
808         struct rfb_softc *rc;
809         fd_set rfds;
810         struct timeval tv;
811         struct timeval prev_tv;
812         int64_t tdiff;
813         int cfd;
814         int err;
815
816         rc = arg;
817         cfd = rc->cfd;
818
819         prev_tv.tv_sec = 0;
820         prev_tv.tv_usec = 0;
821         while (rc->cfd >= 0) {
822                 FD_ZERO(&rfds);
823                 FD_SET(cfd, &rfds);
824                 tv.tv_sec = 0;
825                 tv.tv_usec = CFD_SEL_DELAY;
826
827                 err = select(cfd+1, &rfds, NULL, NULL, &tv);
828                 if (err < 0)
829                         return (NULL);
830
831                 /* Determine if its time to push screen; ~24hz */
832                 gettimeofday(&tv, NULL);
833                 tdiff = timeval_delta(&prev_tv, &tv);
834                 if (tdiff >= SCREEN_POLL_DELAY) {
835                         bool input;
836                         prev_tv.tv_sec = tv.tv_sec;
837                         prev_tv.tv_usec = tv.tv_usec;
838                         input = atomic_exchange(&rc->input_detected, false);
839                         /*
840                          * Refresh the screen on every second trip through the loop,
841                          * or if keyboard/mouse input has been detected.
842                          */
843                         if ((++rc->wrcount & 1) || input) {
844                                 if (rfb_send_screen(rc, cfd) <= 0) {
845                                         return (NULL);
846                                 }
847                         }
848                 } else {
849                         /* sleep */
850                         usleep(SCREEN_POLL_DELAY - tdiff);
851                 }
852         }
853
854         return (NULL);
855 }
856
857 void
858 rfb_handle(struct rfb_softc *rc, int cfd)
859 {
860         const char *vbuf = "RFB 003.008\n";
861         unsigned char buf[80];
862         unsigned char *message = NULL;
863
864 #ifndef NO_OPENSSL
865         unsigned char challenge[AUTH_LENGTH];
866         unsigned char keystr[PASSWD_LENGTH];
867         unsigned char crypt_expected[AUTH_LENGTH];
868
869         DES_key_schedule ks;
870         int i;
871 #endif
872         uint8_t client_ver;
873         uint8_t auth_type;
874         pthread_t tid;
875         uint32_t sres = 0;
876         int len;
877         int perror = 1;
878
879         rc->cfd = cfd;
880
881         /* 1a. Send server version */
882         stream_write(cfd, vbuf, strlen(vbuf));
883
884         /* 1b. Read client version */
885         len = stream_read(cfd, buf, VERSION_LENGTH);
886         if (len == VERSION_LENGTH && !strncmp(vbuf, buf, VERSION_LENGTH - 2)) {
887                 client_ver = buf[VERSION_LENGTH - 2];
888         }
889         if (client_ver != CVERS_3_8 && client_ver != CVERS_3_7) {
890                 /* only recognize 3.3, 3.7 & 3.8. Others dflt to 3.3 */
891                 client_ver = CVERS_3_3;
892         }
893
894         /* 2a. Send security type */
895         buf[0] = 1;
896
897         /* In versions 3.7 & 3.8, it's 2-way handshake */
898         /* For version 3.3, server says what the authentication type must be */
899 #ifndef NO_OPENSSL
900         if (rc->password) {
901                 auth_type = SECURITY_TYPE_VNC_AUTH;
902         } else {
903                 auth_type = SECURITY_TYPE_NONE;
904         }
905 #else
906         auth_type = SECURITY_TYPE_NONE;
907 #endif
908
909         switch (client_ver) {
910         case CVERS_3_7:
911         case CVERS_3_8:
912                 buf[0] = 1;
913                 buf[1] = auth_type;
914                 stream_write(cfd, buf, 2);
915
916                 /* 2b. Read agreed security type */
917                 len = stream_read(cfd, buf, 1);
918                 if (buf[0] != auth_type) {
919                         /* deny */
920                         sres = htonl(1);
921                         message = "Auth failed: authentication type mismatch";
922                         goto report_and_done;
923                 }
924                 break;
925         case CVERS_3_3:
926         default:
927                 be32enc(buf, auth_type);
928                 stream_write(cfd, buf, 4);
929                 break;
930         }
931
932         /* 2c. Do VNC authentication */
933         switch (auth_type) {
934         case SECURITY_TYPE_NONE:
935                 break;
936         case SECURITY_TYPE_VNC_AUTH:
937                 /*
938                  * The client encrypts the challenge with DES, using a password
939                  * supplied by the user as the key.
940                  * To form the key, the password is truncated to
941                  * eight characters, or padded with null bytes on the right.
942                  * The client then sends the resulting 16-bytes response.
943                  */
944 #ifndef NO_OPENSSL
945                 strncpy(keystr, rc->password, PASSWD_LENGTH);
946
947                 /* VNC clients encrypts the challenge with all the bit fields
948                  * in each byte of the password mirrored.
949                  * Here we flip each byte of the keystr.
950                  */
951                 for (i = 0; i < PASSWD_LENGTH; i++) {
952                         keystr[i] = (keystr[i] & 0xF0) >> 4
953                                   | (keystr[i] & 0x0F) << 4;
954                         keystr[i] = (keystr[i] & 0xCC) >> 2
955                                   | (keystr[i] & 0x33) << 2;
956                         keystr[i] = (keystr[i] & 0xAA) >> 1
957                                   | (keystr[i] & 0x55) << 1;
958                 }
959
960                 /* Initialize a 16-byte random challenge */
961                 arc4random_buf(challenge, sizeof(challenge));
962                 stream_write(cfd, challenge, AUTH_LENGTH);
963
964                 /* Receive the 16-byte challenge response */
965                 stream_read(cfd, buf, AUTH_LENGTH);
966
967                 memcpy(crypt_expected, challenge, AUTH_LENGTH);
968
969                 /* Encrypt the Challenge with DES */
970                 DES_set_key((const_DES_cblock *)keystr, &ks);
971                 DES_ecb_encrypt((const_DES_cblock *)challenge,
972                                 (const_DES_cblock *)crypt_expected,
973                                 &ks, DES_ENCRYPT);
974                 DES_ecb_encrypt((const_DES_cblock *)(challenge + PASSWD_LENGTH),
975                                 (const_DES_cblock *)(crypt_expected +
976                                 PASSWD_LENGTH),
977                                 &ks, DES_ENCRYPT);
978
979                 if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) {
980                         message = "Auth Failed: Invalid Password.";
981                         sres = htonl(1);
982                 } else {
983                         sres = 0;
984                 }
985 #else
986                 sres = htonl(1);
987                 WPRINTF(("Auth not supported, no OpenSSL in your system"));
988 #endif
989
990                 break;
991         }
992
993         switch (client_ver) {
994         case CVERS_3_7:
995         case CVERS_3_8:
996 report_and_done:
997                 /* 2d. Write back a status */
998                 stream_write(cfd, &sres, 4);
999
1000                 if (sres) {
1001                         /* 3.7 does not want string explaining cause */
1002                         if (client_ver == CVERS_3_8) {
1003                                 be32enc(buf, strlen(message));
1004                                 stream_write(cfd, buf, 4);
1005                                 stream_write(cfd, message, strlen(message));
1006                         }
1007                         goto done;
1008                 }
1009                 break;
1010         case CVERS_3_3:
1011         default:
1012                 /* for VNC auth case send status */
1013                 if (auth_type == SECURITY_TYPE_VNC_AUTH) {
1014                         /* 2d. Write back a status */
1015                         stream_write(cfd, &sres, 4);
1016                 }
1017                 if (sres) {
1018                         goto done;
1019                 }
1020                 break;
1021         }
1022         /* 3a. Read client shared-flag byte */
1023         len = stream_read(cfd, buf, 1);
1024
1025         /* 4a. Write server-init info */
1026         rfb_send_server_init_msg(cfd);
1027
1028         if (!rc->zbuf) {
1029                 rc->zbuf = malloc(RFB_ZLIB_BUFSZ + 16);
1030                 assert(rc->zbuf != NULL);
1031         }
1032
1033         perror = pthread_create(&tid, NULL, rfb_wr_thr, rc);
1034         if (perror == 0)
1035                 pthread_set_name_np(tid, "rfbout");
1036
1037         /* Now read in client requests. 1st byte identifies type */
1038         for (;;) {
1039                 len = read(cfd, buf, 1);
1040                 if (len <= 0) {
1041                         DPRINTF(("rfb client exiting"));
1042                         break;
1043                 }
1044
1045                 switch (buf[0]) {
1046                 case CS_SET_PIXEL_FORMAT:
1047                         rfb_recv_set_pixfmt_msg(rc, cfd);
1048                         break;
1049                 case CS_SET_ENCODINGS:
1050                         rfb_recv_set_encodings_msg(rc, cfd);
1051                         break;
1052                 case CS_UPDATE_MSG:
1053                         rfb_recv_update_msg(rc, cfd);
1054                         break;
1055                 case CS_KEY_EVENT:
1056                         rfb_recv_key_msg(rc, cfd);
1057                         break;
1058                 case CS_POINTER_EVENT:
1059                         rfb_recv_ptr_msg(rc, cfd);
1060                         break;
1061                 case CS_CUT_TEXT:
1062                         rfb_recv_cuttext_msg(rc, cfd);
1063                         break;
1064                 case CS_MSG_CLIENT_QEMU:
1065                         rfb_recv_client_msg(rc, cfd);
1066                         break;
1067                 default:
1068                         WPRINTF(("rfb unknown cli-code %d!", buf[0] & 0xff));
1069                         goto done;
1070                 }
1071         }
1072 done:
1073         rc->cfd = -1;
1074         if (perror == 0)
1075                 pthread_join(tid, NULL);
1076         if (rc->enc_zlib_ok)
1077                 deflateEnd(&rc->zstream);
1078 }
1079
1080 static void *
1081 rfb_thr(void *arg)
1082 {
1083         struct rfb_softc *rc;
1084         sigset_t set;
1085
1086         int cfd;
1087
1088         rc = arg;
1089
1090         sigemptyset(&set);
1091         sigaddset(&set, SIGPIPE);
1092         if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) {
1093                 perror("pthread_sigmask");
1094                 return (NULL);
1095         }
1096
1097         for (;;) {
1098                 rc->enc_raw_ok = false;
1099                 rc->enc_zlib_ok = false;
1100                 rc->enc_resize_ok = false;
1101                 rc->enc_extkeyevent_ok = false;
1102
1103                 rc->enc_extkeyevent_send = false;
1104
1105                 cfd = accept(rc->sfd, NULL, NULL);
1106                 if (rc->conn_wait) {
1107                         pthread_mutex_lock(&rc->mtx);
1108                         pthread_cond_signal(&rc->cond);
1109                         pthread_mutex_unlock(&rc->mtx);
1110                         rc->conn_wait = 0;
1111                 }
1112                 rfb_handle(rc, cfd);
1113                 close(cfd);
1114         }
1115
1116         /* NOTREACHED */
1117         return (NULL);
1118 }
1119
1120 static int
1121 sse42_supported(void)
1122 {
1123         u_int cpu_registers[4], ecx;
1124
1125         do_cpuid(1, cpu_registers);
1126
1127         ecx = cpu_registers[2];
1128
1129         return ((ecx & CPUID2_SSE42) != 0);
1130 }
1131
1132 int
1133 rfb_init(char *hostname, int port, int wait, char *password)
1134 {
1135         int e;
1136         char servname[6];
1137         struct rfb_softc *rc;
1138         struct addrinfo *ai = NULL;
1139         struct addrinfo hints;
1140         int on = 1;
1141         int cnt;
1142 #ifndef WITHOUT_CAPSICUM
1143         cap_rights_t rights;
1144 #endif
1145
1146         rc = calloc(1, sizeof(struct rfb_softc));
1147
1148         cnt = howmany(RFB_MAX_WIDTH, PIX_PER_CELL) *
1149             howmany(RFB_MAX_HEIGHT, PIX_PER_CELL);
1150         rc->crc = calloc(cnt, sizeof(uint32_t));
1151         rc->crc_tmp = calloc(cnt, sizeof(uint32_t));
1152         rc->crc_width = RFB_MAX_WIDTH;
1153         rc->crc_height = RFB_MAX_HEIGHT;
1154         rc->sfd = -1;
1155
1156         rc->password = password;
1157
1158         snprintf(servname, sizeof(servname), "%d", port ? port : 5900);
1159
1160         if (!hostname || strlen(hostname) == 0)
1161 #if defined(INET)
1162                 hostname = "127.0.0.1";
1163 #elif defined(INET6)
1164                 hostname = "[::1]";
1165 #endif
1166
1167         memset(&hints, 0, sizeof(hints));
1168         hints.ai_family = AF_UNSPEC;
1169         hints.ai_socktype = SOCK_STREAM;
1170         hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE;
1171
1172         if ((e = getaddrinfo(hostname, servname, &hints, &ai)) != 0) {
1173                 EPRINTLN("getaddrinfo: %s", gai_strerror(e));
1174                 goto error;
1175         }
1176
1177         rc->sfd = socket(ai->ai_family, ai->ai_socktype, 0);
1178         if (rc->sfd < 0) {
1179                 perror("socket");
1180                 goto error;
1181         }
1182
1183         setsockopt(rc->sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1184
1185         if (bind(rc->sfd, ai->ai_addr, ai->ai_addrlen) < 0) {
1186                 perror("bind");
1187                 goto error;
1188         }
1189
1190         if (listen(rc->sfd, 1) < 0) {
1191                 perror("listen");
1192                 goto error;
1193         }
1194
1195 #ifndef WITHOUT_CAPSICUM
1196         cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE);
1197         if (caph_rights_limit(rc->sfd, &rights) == -1)
1198                 errx(EX_OSERR, "Unable to apply rights for sandbox");
1199 #endif
1200
1201         rc->hw_crc = sse42_supported();
1202
1203         rc->conn_wait = wait;
1204         if (wait) {
1205                 pthread_mutex_init(&rc->mtx, NULL);
1206                 pthread_cond_init(&rc->cond, NULL);
1207         }
1208
1209         pthread_create(&rc->tid, NULL, rfb_thr, rc);
1210         pthread_set_name_np(rc->tid, "rfb");
1211
1212         if (wait) {
1213                 DPRINTF(("Waiting for rfb client..."));
1214                 pthread_mutex_lock(&rc->mtx);
1215                 pthread_cond_wait(&rc->cond, &rc->mtx);
1216                 pthread_mutex_unlock(&rc->mtx);
1217                 DPRINTF(("rfb client connected"));
1218         }
1219
1220         freeaddrinfo(ai);
1221         return (0);
1222
1223  error:
1224         if (ai != NULL)
1225                 freeaddrinfo(ai);
1226         if (rc->sfd != -1)
1227                 close(rc->sfd);
1228         free(rc->crc);
1229         free(rc->crc_tmp);
1230         free(rc);
1231         return (-1);
1232 }