Re: [gtk-vnc-devel] PATCH: Support Vino's TLS auth scheme
- From: "Daniel P. Berrange" <berrange redhat com>
- To: Jonh Wendell <jwendell gnome org>
- Cc: gtk-vnc-devel List <gtk-vnc-devel lists sourceforge net>
- Subject: Re: [gtk-vnc-devel] PATCH: Support Vino's TLS auth scheme
- Date: Mon, 10 Sep 2007 17:36:21 +0100
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]