[gtk-vnc-devel] auth patch



Hi folks.

Here is the initial draft for the authentication on gtk-vnc.
Well, i'd like to comment it here, but it's too late and i need to
sleep :)

Let's discuss it here, or, eventually on IRC.

Bye,
-- 
Jonh Wendell
jonh wendell gmail com (MSN / Google Talk)

Linux User #114432
https://launchpad.net/~wendell
diff -r 0a645e462b27 src/gvnc.c
--- a/src/gvnc.c	Wed Jun 20 17:33:43 2007 -0300
+++ b/src/gvnc.c	Wed Jun 20 23:45:50 2007 -0300
@@ -71,9 +71,11 @@ struct gvnc
 	int width;
 	int height;
 	char *name;
+	char *password;
 
 	int major;
 	int minor;
+	int auth_type;
 	gnutls_session_t tls_session;
 
 	char read_buffer[4096];
@@ -122,7 +124,7 @@ enum {
 };
 
 
-#if 0
+#if 1
 #define GVNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
 #else
 #define GVNC_DEBUG(fmt, ...) do { } while (0)
@@ -858,8 +860,8 @@ static void gvnc_framebuffer_update(stru
 				    uint16_t x, uint16_t y,
 				    uint16_t width, uint16_t height)
 {
-	GVNC_DEBUG("FramebufferUpdate(%d, %d, %d, %d, %d)\n",
-		   etype, x, y, width, height);
+//	GVNC_DEBUG("FramebufferUpdate(%d, %d, %d, %d, %d)\n",
+//		   etype, x, y, width, height);
 
 	switch (etype) {
 	case 0: /* Raw */
@@ -1011,19 +1013,20 @@ static gboolean gvnc_check_auth_result(s
 	return FALSE;
 }
 
-static gboolean gvnc_perform_auth_vnc(struct gvnc *gvnc, const char *password)
+static gboolean gvnc_perform_auth_vnc(struct gvnc *gvnc)
 {
 	uint8_t challenge[16];
 	uint8_t key[8];
 
 	GVNC_DEBUG("Do Challenge\n");
-	if (!password)
+	GVNC_DEBUG("Password: %s\n", gvnc->password);
+	if (!gvnc->password)
 		return FALSE;
 
 	gvnc_read(gvnc, challenge, 16);
 
 	memset(key, 0, 8);
-	strncpy((char*)key, (char*)password, 8);
+	strncpy((char*)key, (char*)gvnc->password, 8);
 
 	deskey(key, EN0);
 	des(challenge, challenge);
@@ -1131,7 +1134,7 @@ static gboolean gvnc_start_tls(struct gv
 	}
 }
 
-static gboolean gvnc_perform_auth_vencrypt(struct gvnc *gvnc, const char *password)
+static gboolean gvnc_perform_auth_vencrypt(struct gvnc *gvnc)
 {
 	int major, minor, status, wantAuth = GVNC_AUTH_INVALID, anonTLS;
 	unsigned int nauth, i;
@@ -1222,14 +1225,14 @@ static gboolean gvnc_perform_auth_vencry
 	case GVNC_AUTH_VENCRYPT_TLSVNC:
 	case GVNC_AUTH_VENCRYPT_X509VNC:
 		GVNC_DEBUG("Handing off to VNC auth\n");
-		return gvnc_perform_auth_vnc(gvnc, password);
+		return gvnc_perform_auth_vnc(gvnc);
 
 	default:
 		return FALSE;
 	}
 }
 
-static gboolean gvnc_perform_auth(struct gvnc *gvnc, const char *password)
+int gvnc_auth_init(struct gvnc *gvnc)
 {
 	int wantAuth = GVNC_AUTH_INVALID;
 	unsigned int nauth, i;
@@ -1241,14 +1244,14 @@ static gboolean gvnc_perform_auth(struct
 	} else {
 		nauth = gvnc_read_u8(gvnc);
 		if (gvnc_has_error(gvnc))
-			return FALSE;
+			return -1;
 
 		if (nauth == 0)
 			return gvnc_check_auth_result(gvnc);
 
 		if (nauth > sizeof(auth)) {
 			gvnc->has_error = TRUE;
-			return FALSE;
+			return -1;
 		}
 		for (i = 0 ; i < nauth ; i++)
 			auth[i] = gvnc_read_u8(gvnc);
@@ -1259,7 +1262,7 @@ static gboolean gvnc_perform_auth(struct
 	}
 
 	if (gvnc->has_error)
-		return FALSE;
+		return -1;
 
 	for (i = 0 ; i < nauth ; i++) {
 		if (auth[i] == GVNC_AUTH_NONE ||
@@ -1276,16 +1279,23 @@ static gboolean gvnc_perform_auth(struct
 		gvnc_flush(gvnc);
 	}
 
-	switch (wantAuth) {
+	gvnc->auth_type = wantAuth;
+	return wantAuth;
+}
+
+static gboolean gvnc_perform_auth(struct gvnc *gvnc)
+{
+
+	switch (gvnc->auth_type) {
 	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, password);
+		return gvnc_perform_auth_vnc(gvnc);
 
 	case GVNC_AUTH_VENCRYPT:
-		return gvnc_perform_auth_vencrypt(gvnc, password);
+		return gvnc_perform_auth_vencrypt(gvnc);
 
 	default:
 		return FALSE;
@@ -1294,12 +1304,11 @@ static gboolean gvnc_perform_auth(struct
 	return TRUE;
 }
 
-struct gvnc *gvnc_connect(GIOChannel *channel, gboolean shared_flag, const char *password)
+struct gvnc *gvnc_new(GIOChannel *channel)
 {
 	int s;
 	int ret;
 	char version[13];
-	uint32_t n_name;
 	struct gvnc *gvnc = NULL;
 
 	s = g_io_channel_unix_get_fd(channel);
@@ -1315,6 +1324,7 @@ struct gvnc *gvnc_connect(GIOChannel *ch
 
 	gvnc->channel = channel;
 	gvnc->absolute = 1;
+	gvnc->password = NULL;
 
 	gvnc_read(gvnc, version, 12);
 	version[12] = 0;
@@ -1337,7 +1347,18 @@ struct gvnc *gvnc_connect(GIOChannel *ch
 	gvnc_flush(gvnc);
 	GVNC_DEBUG("Negotiated protocol %d %d\n", gvnc->major, gvnc->minor);
 
-	if (!gvnc_perform_auth(gvnc, password)) {
+	return gvnc;
+
+ error:
+	free(gvnc);
+	return NULL;
+}
+
+gboolean gvnc_go(struct gvnc *gvnc, gboolean shared_flag)
+{
+	uint32_t n_name;
+
+	if (!gvnc_perform_auth(gvnc)) {
 		GVNC_DEBUG("Auth failed\n");
 		goto error;
 	}
@@ -1363,11 +1384,11 @@ struct gvnc *gvnc_connect(GIOChannel *ch
 
 	gvnc_resize(gvnc, gvnc->width, gvnc->height);
 
-	return gvnc;
+	return TRUE;
 
  error:
 	free(gvnc);
-	return NULL;
+	return FALSE;
 }
 
 gboolean gvnc_set_local(struct gvnc *gvnc, struct framebuffer *fb)
@@ -1434,6 +1455,13 @@ gboolean gvnc_set_vnc_ops(struct gvnc *g
 	return gvnc_has_error(gvnc);
 }
 
+void gvnc_set_password(struct gvnc *gvnc, const char *password)
+{
+	if (gvnc->password)
+		free (gvnc->password);
+	gvnc->password = strdup (password);
+}
+
 const char *gvnc_get_name(struct gvnc *gvnc)
 {
 	return gvnc->name;
@@ -1447,6 +1475,11 @@ int gvnc_get_height(struct gvnc *gvnc)
 int gvnc_get_height(struct gvnc *gvnc)
 {
 	return gvnc->height;
+}
+
+int gvnc_get_auth_type(struct gvnc *gvnc)
+{
+	return gvnc->auth_type;
 }
 
 /*
diff -r 0a645e462b27 src/gvnc.h
--- a/src/gvnc.h	Wed Jun 20 17:33:43 2007 -0300
+++ b/src/gvnc.h	Wed Jun 20 23:45:50 2007 -0300
@@ -55,7 +55,9 @@ struct framebuffer
 	int green_shift;
 };
 
-struct gvnc *gvnc_connect(GIOChannel *channel, gboolean shared_flag, const char *password);
+struct gvnc *gvnc_new(GIOChannel *channel);
+int          gvnc_auth_init(struct gvnc *gvnc);
+gboolean     gvnc_go(struct gvnc *gvnc, gboolean shared_flag);
 
 gboolean gvnc_server_message(struct gvnc *gvnc);
 
@@ -87,8 +89,11 @@ gboolean gvnc_set_vnc_ops(struct gvnc *g
 
 gboolean gvnc_shared_memory_enabled(struct gvnc *gvnc);
 
+void     gvnc_set_password(struct gvnc *gvnc, const char *password);
+
 const char *gvnc_get_name(struct gvnc *gvnc);
 int gvnc_get_width(struct gvnc *gvnc);
 int gvnc_get_height(struct gvnc *gvnc);
+int gvnc_get_auth_type(struct gvnc *gvnc);
 
 #endif
diff -r 0a645e462b27 src/vncdisplay.c
--- a/src/vncdisplay.c	Wed Jun 20 17:33:43 2007 -0300
+++ b/src/vncdisplay.c	Wed Jun 20 23:45:44 2007 -0300
@@ -38,7 +38,6 @@ struct _VncDisplayPrivate
 	int button_mask;
 	int last_x;
 	int last_y;
-	const char *password;
 
 	int absolute;
 
@@ -48,6 +47,7 @@ struct _VncDisplayPrivate
 /* Signals */
 enum
 {
+  VNC_AUTHENTICATION_REQUIRED,
   VNC_INITIALIZED,
   LAST_SIGNAL
 };
@@ -371,7 +371,7 @@ static void *vnc_coroutine(void *opaque)
 	VncDisplay *obj = VNC_DISPLAY(opaque);
 	VncDisplayPrivate *priv = obj->priv;
 	int32_t encodings[] = { -223, -258, -257, 5, 1, 0 };
-	int ret;
+	int ret, auth_type;
 	struct vnc_ops ops = {
 		.update = on_update,
 		.resize = on_resize,
@@ -380,8 +380,16 @@ static void *vnc_coroutine(void *opaque)
 		.user = obj,
 	};
 
-	priv->gvnc = gvnc_connect(priv->channel, FALSE, priv->password);
+	priv->gvnc = gvnc_new(priv->channel);
 	if (priv->gvnc == NULL)
+		return NULL;
+
+	auth_type = gvnc_auth_init(priv->gvnc);
+	if (auth_type == 2)
+		g_signal_emit (G_OBJECT (obj),
+		               signals[VNC_AUTHENTICATION_REQUIRED],
+		               0);
+	if (!gvnc_go(priv->gvnc, FALSE))
 		return NULL;
 
 	g_signal_emit (G_OBJECT (obj),
@@ -429,6 +437,16 @@ static void vnc_display_class_init(VncDi
 static void vnc_display_class_init(VncDisplayClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	signals[VNC_AUTHENTICATION_REQUIRED] =
+		g_signal_new ("authentication-required",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (VncDisplayClass, vnc_authentication_required),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
 
 	signals[VNC_INITIALIZED] =
 		g_signal_new ("vnc-initialized",
@@ -508,7 +526,7 @@ static void vnc_display_init(GTypeInstan
 
 void vnc_display_set_password(VncDisplay *obj, const gchar *password)
 {
-	obj->priv->password = password;
+	gvnc_set_password (obj->priv->gvnc, password);
 }
 
 void vnc_display_set_use_shm(VncDisplay *obj, gboolean enable)
@@ -541,6 +559,12 @@ GType vnc_display_get_type(void)
 
 	return type;
 }
+int vnc_display_get_auth_type(VncDisplay *obj)
+{
+  g_return_val_if_fail (VNC_IS_DISPLAY (obj), -1);
+
+  return gvnc_get_auth_type (obj->priv->gvnc);
+}
 
 int vnc_display_get_width(VncDisplay *obj)
 {
diff -r 0a645e462b27 src/vncdisplay.h
--- a/src/vncdisplay.h	Wed Jun 20 17:33:43 2007 -0300
+++ b/src/vncdisplay.h	Wed Jun 20 23:45:44 2007 -0300
@@ -48,6 +48,7 @@ struct _VncDisplayClass
 
 	/* Signals */
 	void		(* vnc_initialized)	(VncDisplay *display);
+	void		(* vnc_authentication_required)	(VncDisplay *display);
 
 	int enter_grab_event_id;
 	int leave_grab_event_id;
@@ -61,6 +62,7 @@ void		vnc_display_open(VncDisplay *obj, 
 void		vnc_display_open(VncDisplay *obj, int fd);
 
 void		vnc_display_set_password(VncDisplay *obj, const gchar *password);
+int			vnc_display_get_auth_type(VncDisplay *obj);
 
 void		vnc_display_set_use_shm(VncDisplay *obj, gboolean enable);
 


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