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



On Sun, Sep 09, 2007 at 09:03:53AM -0300, Jonh Wendell wrote:
> Em Qui, 2007-09-06 às 20:51 +0100, Daniel P. Berrange escreveu:
> > 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.
> 
> Hi, Dan.
> 
> The patch works if i choose no password in vino (auth type "none").
> If i put a password in vino (auth type 2), it doesn't work:

I was forgetting to request a password credential in the TLS sub-auth types
for VINO so the client disconnected. Attaching an updated patch

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	Mon Sep 10 12:34:46 2007 -0400
@@ -1466,6 +1466,10 @@ gboolean gvnc_wants_credential_password(
         if (gvnc->auth_type == GVNC_AUTH_VNC)
                 return TRUE;
 
+        if (gvnc->auth_type == GVNC_AUTH_TLS &&
+	    gvnc->auth_subtype == GVNC_AUTH_VNC)
+                return TRUE;
+
         if (gvnc->auth_type == GVNC_AUTH_VENCRYPT) {
                 if (gvnc->auth_subtype == GVNC_AUTH_VENCRYPT_PLAIN ||
                     gvnc->auth_subtype == GVNC_AUTH_VENCRYPT_TLSVNC ||
@@ -1556,6 +1560,73 @@ 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;
+
+	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 +1800,11 @@ static gboolean gvnc_perform_auth(struct
 		return TRUE;
 	case GVNC_AUTH_VNC:
 		return gvnc_perform_auth_vnc(gvnc);
+
+	case GVNC_AUTH_TLS:
+		if (gvnc->minor < 7)
+			return FALSE;
+		return gvnc_perform_auth_tls(gvnc);
 
 	case GVNC_AUTH_VENCRYPT:
 		return gvnc_perform_auth_vencrypt(gvnc);
@@ -2023,6 +2099,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 +2113,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 17:31:45 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]