Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131665672
D10818.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D10818.diff
View Options
Index: head/usr.sbin/bhyve/Makefile
===================================================================
--- head/usr.sbin/bhyve/Makefile
+++ head/usr.sbin/bhyve/Makefile
@@ -2,6 +2,8 @@
# $FreeBSD$
#
+.include <src.opts.mk>
+
PROG= bhyve
PACKAGE= bhyve
@@ -62,6 +64,12 @@
SRCS+= vmm_instruction_emul.c
LIBADD= vmmapi md pthread z
+
+.if ${MK_OPENSSL} == "no"
+CFLAGS+=-DNO_OPENSSL
+.else
+LIBADD+= crypto
+.endif
CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/e1000
CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/mii
Index: head/usr.sbin/bhyve/bhyve.8
===================================================================
--- head/usr.sbin/bhyve/bhyve.8
+++ head/usr.sbin/bhyve/bhyve.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 3, 2017
+.Dd May 22, 2017
.Dt BHYVE 8
.Os
.Sh NAME
@@ -309,7 +309,7 @@
.Pp
Framebuffer devices:
.Bl -tag -width 10n
-.It Oo rfb= Ns Oo Ar IP: Oc Ns Ar port Oc Ns Oo ,w= Ns Ar width Oc Ns Oo ,h= Ns Ar height Oc Ns Oo ,vga= Ns Ar vgaconf Oc Ns Oo Ns ,wait Oc
+.It Oo rfb= Ns Oo Ar IP: Oc Ns Ar port Oc Ns Oo ,w= Ns Ar width Oc Ns Oo ,h= Ns Ar height Oc Ns Oo ,vga= Ns Ar vgaconf Oc Ns Oo Ns ,wait Oc Ns Oo ,password= Ns Ar password Oc
.Bl -tag -width 8n
.It Ar IP:port
An
@@ -368,6 +368,11 @@
to only boot upon the initiation of a VNC connection, simplifying the installation
of operating systems that require immediate keyboard input.
This can be removed for post-installation use.
+.It password
+This type of authentication is known to be cryptographically weak and is not
+intended for use on untrusted networks.
+Many implementations will want to use stronger security, such as running
+the session over an encrypted channel provided by IPsec or SSH.
.El
.El
.Pp
Index: head/usr.sbin/bhyve/pci_fbuf.c
===================================================================
--- head/usr.sbin/bhyve/pci_fbuf.c
+++ head/usr.sbin/bhyve/pci_fbuf.c
@@ -93,6 +93,7 @@
/* rfb server */
char *rfb_host;
+ char *rfb_password;
int rfb_port;
int rfb_wait;
int vga_enabled;
@@ -285,7 +286,8 @@
goto done;
} else if (sc->memregs.height == 0)
sc->memregs.height = 1080;
-
+ } else if (!strcmp(xopts, "password")) {
+ sc->rfb_password = config;
} else {
pci_fbuf_usage(xopts);
ret = -1;
@@ -407,7 +409,7 @@
memset((void *)sc->fb_base, 0, FB_SIZE);
- error = rfb_init(sc->rfb_host, sc->rfb_port, sc->rfb_wait);
+ error = rfb_init(sc->rfb_host, sc->rfb_port, sc->rfb_wait, sc->rfb_password);
done:
if (error)
free(sc);
Index: head/usr.sbin/bhyve/rfb.h
===================================================================
--- head/usr.sbin/bhyve/rfb.h
+++ head/usr.sbin/bhyve/rfb.h
@@ -31,6 +31,6 @@
#define RFB_PORT 5900
-int rfb_init(char *hostname, int port, int wait);
+int rfb_init(char *hostname, int port, int wait, char *password);
#endif /* _RFB_H_ */
Index: head/usr.sbin/bhyve/rfb.c
===================================================================
--- head/usr.sbin/bhyve/rfb.c
+++ head/usr.sbin/bhyve/rfb.c
@@ -60,10 +60,23 @@
#include "rfb.h"
#include "sockstream.h"
+#ifndef NO_OPENSSL
+#include <openssl/des.h>
+#endif
+
static int rfb_debug = 0;
#define DPRINTF(params) if (rfb_debug) printf params
#define WPRINTF(params) printf params
+#define AUTH_LENGTH 16
+#define PASSWD_LENGTH 8
+
+#define SECURITY_TYPE_NONE 1
+#define SECURITY_TYPE_VNC_AUTH 2
+
+#define AUTH_FAILED_UNAUTH 1
+#define AUTH_FAILED_ERROR 2
+
struct rfb_softc {
int sfd;
pthread_t tid;
@@ -72,10 +85,12 @@
int width, height;
- bool enc_raw_ok;
- bool enc_zlib_ok;
- bool enc_resize_ok;
+ char *password;
+ bool enc_raw_ok;
+ bool enc_zlib_ok;
+ bool enc_resize_ok;
+
z_stream zstream;
uint8_t *zbuf;
int zbuflen;
@@ -208,7 +223,7 @@
rfb_send_resize_update_msg(struct rfb_softc *rc, int cfd)
{
struct rfb_srvr_updt_msg supdt_msg;
- struct rfb_srvr_rect_hdr srect_hdr;
+ struct rfb_srvr_rect_hdr srect_hdr;
/* Number of rectangles: 1 */
supdt_msg.type = 0;
@@ -739,8 +754,19 @@
{
const char *vbuf = "RFB 003.008\n";
unsigned char buf[80];
+ unsigned char *message;
+
+#ifndef NO_OPENSSL
+ unsigned char challenge[AUTH_LENGTH];
+ unsigned char keystr[PASSWD_LENGTH];
+ unsigned char crypt_expected[AUTH_LENGTH];
+
+ DES_key_schedule ks;
+ int i;
+#endif
+
pthread_t tid;
- uint32_t sres;
+ uint32_t sres;
int len;
rc->cfd = cfd;
@@ -751,19 +777,91 @@
/* 1b. Read client version */
len = read(cfd, buf, sizeof(buf));
- /* 2a. Send security type 'none' */
+ /* 2a. Send security type */
buf[0] = 1;
- buf[1] = 1; /* none */
+#ifndef NO_OPENSSL
+ if (rc->password)
+ buf[1] = SECURITY_TYPE_VNC_AUTH;
+ else
+ buf[1] = SECURITY_TYPE_NONE;
+#else
+ buf[1] = SECURITY_TYPE_NONE;
+#endif
+
stream_write(cfd, buf, 2);
-
/* 2b. Read agreed security type */
len = stream_read(cfd, buf, 1);
- /* 2c. Write back a status of 0 */
- sres = 0;
+ /* 2c. Do VNC authentication */
+ switch (buf[0]) {
+ case SECURITY_TYPE_NONE:
+ sres = 0;
+ break;
+ case SECURITY_TYPE_VNC_AUTH:
+ /*
+ * The client encrypts the challenge with DES, using a password
+ * supplied by the user as the key.
+ * To form the key, the password is truncated to
+ * eight characters, or padded with null bytes on the right.
+ * The client then sends the resulting 16-bytes response.
+ */
+#ifndef NO_OPENSSL
+ strncpy(keystr, rc->password, PASSWD_LENGTH);
+
+ /* VNC clients encrypts the challenge with all the bit fields
+ * in each byte of the password mirrored.
+ * Here we flip each byte of the keystr.
+ */
+ for (i = 0; i < PASSWD_LENGTH; i++) {
+ keystr[i] = (keystr[i] & 0xF0) >> 4
+ | (keystr[i] & 0x0F) << 4;
+ keystr[i] = (keystr[i] & 0xCC) >> 2
+ | (keystr[i] & 0x33) << 2;
+ keystr[i] = (keystr[i] & 0xAA) >> 1
+ | (keystr[i] & 0x55) << 1;
+ }
+
+ /* Initialize a 16-byte random challenge */
+ arc4random_buf(challenge, sizeof(challenge));
+ stream_write(cfd, challenge, AUTH_LENGTH);
+
+ /* Receive the 16-byte challenge response */
+ stream_read(cfd, buf, AUTH_LENGTH);
+
+ memcpy(crypt_expected, challenge, AUTH_LENGTH);
+
+ /* Encrypt the Challenge with DES */
+ DES_set_key((C_Block *)keystr, &ks);
+ DES_ecb_encrypt((C_Block *)challenge,
+ (C_Block *)crypt_expected, &ks, DES_ENCRYPT);
+ DES_ecb_encrypt((C_Block *)(challenge + PASSWD_LENGTH),
+ (C_Block *)(crypt_expected + PASSWD_LENGTH),
+ &ks, DES_ENCRYPT);
+
+ if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) {
+ message = "Auth Failed: Invalid Password.";
+ sres = htonl(1);
+ } else
+ sres = 0;
+#else
+ sres = 0;
+ WPRINTF(("Auth not supported, no OpenSSL in your system"));
+#endif
+
+ break;
+ }
+
+ /* 2d. Write back a status */
stream_write(cfd, &sres, 4);
+ if (sres) {
+ *((uint32_t *) buf) = htonl(strlen(message));
+ stream_write(cfd, buf, 4);
+ stream_write(cfd, message, strlen(message));
+ goto done;
+ }
+
/* 3a. Read client shared-flag byte */
len = stream_read(cfd, buf, 1);
@@ -869,7 +967,7 @@
}
int
-rfb_init(char *hostname, int port, int wait)
+rfb_init(char *hostname, int port, int wait, char *password)
{
struct rfb_softc *rc;
struct sockaddr_in sin;
@@ -886,6 +984,8 @@
sizeof(uint32_t));
rc->crc_width = RFB_MAX_WIDTH;
rc->crc_height = RFB_MAX_HEIGHT;
+
+ rc->password = password;
rc->sfd = socket(AF_INET, SOCK_STREAM, 0);
if (rc->sfd < 0) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 11, 4:14 AM (11 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23562560
Default Alt Text
D10818.diff (7 KB)
Attached To
Mode
D10818: VNC authentication based on review D7029
Attached
Detach File
Event Timeline
Log In to Comment