Index: rfb.c =================================================================== --- rfb.c (revision 367059) +++ rfb.c (working copy) @@ -221,6 +221,9 @@ sinfo.pixfmt.red_shift = 16; sinfo.pixfmt.green_shift = 8; sinfo.pixfmt.blue_shift = 0; + sinfo.pixfmt.pad[0] = 0; + sinfo.pixfmt.pad[1] = 0; + sinfo.pixfmt.pad[2] = 0; sinfo.namelen = htonl(strlen("bhyve")); (void)stream_write(cfd, &sinfo, sizeof(sinfo)); (void)stream_write(cfd, "bhyve", strlen("bhyve")); @@ -623,7 +626,7 @@ static void -rfb_recv_update_msg(struct rfb_softc *rc, int cfd, int discardonly) +rfb_recv_update_msg(struct rfb_softc *rc, int cfd) { struct rfb_updt_msg updt_msg; struct bhyvegc_image *gc_image; @@ -638,18 +641,17 @@ updt_msg.width = htons(updt_msg.width); updt_msg.height = htons(updt_msg.height); - if (updt_msg.width != gc_image->width || - updt_msg.height != gc_image->height) { - rc->width = gc_image->width; - rc->height = gc_image->height; - if (rc->enc_resize_ok) - rfb_send_resize_update_msg(rc, cfd); + if (updt_msg.incremental == 0) { + rfb_send_screen(rc, cfd, 1); + } else { + if (updt_msg.width != gc_image->width || + updt_msg.height != gc_image->height) { + rc->width = gc_image->width; + rc->height = gc_image->height; + if (rc->enc_resize_ok) + rfb_send_resize_update_msg(rc, cfd); + } } - - if (discardonly) - return; - - rfb_send_screen(rc, cfd, 1); } static void @@ -756,7 +758,8 @@ DES_key_schedule ks; int i; #endif - + uint8_t client_ver; + uint8_t auth_type; pthread_t tid; uint32_t sres = 0; int len; @@ -769,27 +772,52 @@ /* 1b. Read client version */ len = read(cfd, buf, sizeof(buf)); + if (len == strlen(vbuf) && !strncmp(vbuf, buf, 10)) { + client_ver = buf[10]; + } + if (client_ver != '8' && client_ver != '7') { + /* only recognize 3.3, 3.7 & 3.8. Others dflt to 3.3 */ + client_ver = '3'; + } /* 2a. Send security type */ - buf[0] = 1; + /* In versions 3.7 & 3.8, it's 2-way handshake */ + /* For version 3.3, server says what the authentication type must be */ #ifndef NO_OPENSSL - if (rc->password) - buf[1] = SECURITY_TYPE_VNC_AUTH; - else - buf[1] = SECURITY_TYPE_NONE; + if (rc->password) { + auth_type = SECURITY_TYPE_VNC_AUTH; + } else { + auth_type = SECURITY_TYPE_NONE; + } #else - buf[1] = SECURITY_TYPE_NONE; + auth_type = SECURITY_TYPE_NONE; #endif + switch (client_ver) { + case '7': + case '8': + buf[0] = 1; + buf[1] = auth_type; + stream_write(cfd, buf, 2); - stream_write(cfd, buf, 2); + /* 2b. Read agreed security type */ + len = stream_read(cfd, buf, 1); + if (buf[0] != auth_type) { + /* deny */ + sres = htonl(1); + message = "Auth failed: authentication type mismatch"; + goto report_and_done; + } + break; + case '3': + default: + be32enc(buf, auth_type); + stream_write(cfd, buf, 4); + break; + } - /* 2b. Read agreed security type */ - len = stream_read(cfd, buf, 1); - /* 2c. Do VNC authentication */ - switch (buf[0]) { + switch (auth_type) { case SECURITY_TYPE_NONE: - sres = 0; break; case SECURITY_TYPE_VNC_AUTH: /* @@ -837,10 +865,11 @@ if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) { message = "Auth Failed: Invalid Password."; sres = htonl(1); - } else + } else { sres = 0; + } #else - sres = 0; + sres = htonl(1); WPRINTF(("Auth not supported, no OpenSSL in your system")); #endif @@ -847,16 +876,35 @@ break; } - /* 2d. Write back a status */ - stream_write(cfd, &sres, 4); + switch (client_ver) { + case '7': + case '8': +report_and_done: + /* 2d. Write back a status */ + stream_write(cfd, &sres, 4); - if (sres) { - be32enc(buf, strlen(message)); - stream_write(cfd, buf, 4); - stream_write(cfd, message, strlen(message)); - goto done; + if (sres) { + /* 3.7 does not want string explaining cause */ + if (client_ver == '8') { + be32enc(buf, strlen(message)); + stream_write(cfd, buf, 4); + stream_write(cfd, message, strlen(message)); + } + goto done; + } + break; + case '3': + default: + /* for VNC auth case send status */ + if (auth_type == SECURITY_TYPE_VNC_AUTH) { + /* 2d. Write back a status */ + stream_write(cfd, &sres, 4); + } + if (sres) { + goto done; + } + break; } - /* 3a. Read client shared-flag byte */ len = stream_read(cfd, buf, 1); @@ -868,8 +916,6 @@ assert(rc->zbuf != NULL); } - rfb_send_screen(rc, cfd, 1); - perror = pthread_create(&tid, NULL, rfb_wr_thr, rc); if (perror == 0) pthread_set_name_np(tid, "rfbout"); @@ -890,7 +936,7 @@ rfb_recv_set_encodings_msg(rc, cfd); break; case 3: - rfb_recv_update_msg(rc, cfd, 1); + rfb_recv_update_msg(rc, cfd); break; case 4: rfb_recv_key_msg(rc, cfd);