[gtk-vnc-devel] PATCH: Support Vino's TLS auth scheme



VINO (the GNOME VNC server for remote desktop) implements a TLS authentication
scheme of its own (registered auth #18). The way this works is that the client
request auth 18, and the client+server immediately do a TLS handshake using
anonymous TLS credentials. The protocol then repeats the auth negotiation
again this time choosing either None, or VNC  as the auth type.

This gives data encryption between client & server good enough to prevent 
casual snooping, but it is still susceptible to a man-in-the-middle attack
since it is fixed to use anonymous credentials & no x509 certificates. Given
that we already support anonymous credentials for some of the VeNCrypt auth
sub-types it was trivial to add support for VINO's TLS mode.

So the attached patch implements Vino's TLS...

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
diff -r f869a84aa6c5 src/gvnc.c
--- a/src/gvnc.c	Sat Sep 01 00:19:37 2007 -0300
+++ b/src/gvnc.c	Thu Sep 06 15:43:58 2007 -0400
@@ -1556,6 +1556,75 @@ static gboolean gvnc_has_auth_subtype(gp
 }
 
 
+static gboolean gvnc_perform_auth_tls(struct gvnc *gvnc)
+{
+	int status;
+	unsigned int nauth, i;
+	unsigned int auth[20];
+
+	if (!gvnc_start_tls(gvnc, 1)) {
+		GVNC_DEBUG("Could not start TLS\n");
+		return FALSE;
+	}
+	GVNC_DEBUG("Completed TLS setup\n");
+
+	nauth = gvnc_read_u8(gvnc);
+	if (gvnc_has_error(gvnc))
+		return FALSE;
+
+	if (nauth == 0)
+		return gvnc_check_auth_result(gvnc);
+
+	if (nauth > sizeof(auth)) {
+		GVNC_DEBUG("Too many (%d) auth types\n", nauth);
+		gvnc->has_error = TRUE;
+		return FALSE;
+	}
+	for (i = 0 ; i < nauth ; i++) {
+		auth[i] = gvnc_read_u8(gvnc);
+	}
+
+	for (i = 0 ; i < nauth ; i++) {
+		GVNC_DEBUG("Possible sub-auth %d\n", auth[i]);
+	}
+
+	if (gvnc->has_error || !gvnc->ops.auth_subtype)
+		return FALSE;
+
+	if (!gvnc->ops.auth_subtype(gvnc->ops_data, nauth, auth))
+		gvnc->has_error = TRUE;
+	if (gvnc->has_error)
+		return FALSE;
+
+	GVNC_DEBUG("Waiting for auth subtype\n");
+	g_condition_wait(gvnc_has_auth_subtype, gvnc);
+	if (gvnc->has_error)
+		return FALSE;
+
+	GVNC_DEBUG("Choose auth %d\n", gvnc->auth_subtype);
+
+	if (!gvnc_gather_credentials(gvnc))
+		return FALSE;
+
+	if (gvnc->minor > 6) {
+		gvnc_write_u8(gvnc, gvnc->auth_subtype);
+		gvnc_flush(gvnc);
+	}
+
+	switch (gvnc->auth_subtype) {
+	case GVNC_AUTH_NONE:
+		if (gvnc->minor == 8)
+			return gvnc_check_auth_result(gvnc);
+		return TRUE;
+	case GVNC_AUTH_VNC:
+		return gvnc_perform_auth_vnc(gvnc);
+	default:
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 static gboolean gvnc_perform_auth_vencrypt(struct gvnc *gvnc)
 {
 	int major, minor, status, anonTLS;
@@ -1729,6 +1798,9 @@ static gboolean gvnc_perform_auth(struct
 		return TRUE;
 	case GVNC_AUTH_VNC:
 		return gvnc_perform_auth_vnc(gvnc);
+
+	case GVNC_AUTH_TLS:
+		return gvnc_perform_auth_tls(gvnc);
 
 	case GVNC_AUTH_VENCRYPT:
 		return gvnc_perform_auth_vencrypt(gvnc);
@@ -2023,6 +2095,7 @@ gboolean gvnc_set_auth_type(struct gvnc 
         }
         if (type != GVNC_AUTH_NONE &&
             type != GVNC_AUTH_VNC &&
+            type != GVNC_AUTH_TLS &&
             type != GVNC_AUTH_VENCRYPT) {
                 gvnc->has_error = TRUE;
                 return !gvnc_has_error(gvnc);
@@ -2036,7 +2109,8 @@ gboolean gvnc_set_auth_subtype(struct gv
 gboolean gvnc_set_auth_subtype(struct gvnc *gvnc, unsigned int type)
 {
         GVNC_DEBUG("Requested auth subtype %d\n", type);
-        if (gvnc->auth_type != GVNC_AUTH_VENCRYPT) {
+        if (gvnc->auth_type != GVNC_AUTH_VENCRYPT &&
+	    gvnc->auth_type != GVNC_AUTH_TLS) {
                 gvnc->has_error = TRUE;
 		return !gvnc_has_error(gvnc);
         }
diff -r f869a84aa6c5 src/gvnc.h
--- a/src/gvnc.h	Sat Sep 01 00:19:37 2007 -0300
+++ b/src/gvnc.h	Thu Sep 06 15:28:19 2007 -0400
@@ -83,8 +83,8 @@ typedef enum {
 	GVNC_AUTH_RA2NE = 6,
 	GVNC_AUTH_TIGHT = 16,
 	GVNC_AUTH_ULTRA = 17,
-	GVNC_AUTH_TLS = 18,
-	GVNC_AUTH_VENCRYPT = 19
+	GVNC_AUTH_TLS = 18,  /* Used by VINO */
+	GVNC_AUTH_VENCRYPT = 19 /* Used by VeNCrypt and QEMU */
 } gvnc_auth;
 
 typedef enum {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]