Re: PATCH for sftp-method to use gnome-keyring



	Just reading the patch... I love leaking! :)
New patch attached. (and fixing a leak of password in the current code).


BTW, don't write patches at 6am in the morning the day after last
GUADEC-ES night drinking queimada and sleeping 3 hours.
-- 
Fernando Herrera de las Heras
Onírica: análisis, diseño e implantación de soluciones informáticas
http://www.onirica.com
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-vfs/ChangeLog,v
retrieving revision 1.1806
diff -u -u -r1.1806 ChangeLog
--- ChangeLog	18 May 2004 07:58:40 -0000	1.1806
+++ ChangeLog	24 May 2004 04:55:50 -0000
@@ -1,3 +1,11 @@
+2004-05-24  Fernando Herrera  <fherrera onirica com>
+
+	* modules/sftp-method.c: (invoke_fill_auth), (invoke_full_auth),
+	(invoke_save_auth), (sftp_connect): Get password from keyring if
+	possible. After a correct password is introduced and marked for 
+	"store in keyring" store it. Also handles the case of wrong password
+	in the keyring asking again for it.
+
 2004-05-18  Alexander Larsson  <alexl redhat com>
 
 	* libgnomevfs/gnome-vfs-volume-monitor-daemon.c (get_device_type_from_device_and_mount):
Index: modules/sftp-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/sftp-method.c,v
retrieving revision 1.12
diff -u -u -r1.12 sftp-method.c
--- modules/sftp-method.c	16 May 2004 11:24:56 -0000	1.12
+++ modules/sftp-method.c	24 May 2004 04:55:51 -0000
@@ -846,16 +846,91 @@
 
 
 static gboolean
+invoke_fill_auth (const GnomeVFSURI *uri,
+		  const char *password_line,
+		  char **password_out)
+{
+	gboolean invoked;
+	char *user, *chr, *ptr;
+	char *object, *server = NULL;
+	gboolean passphrase;
+	GnomeVFSModuleCallbackFillAuthenticationIn in_args;
+	GnomeVFSModuleCallbackFillAuthenticationOut out_args;
+
+	passphrase = g_str_has_prefix (password_line, "Enter passphrase for key");
+
+	user = NULL;
+	object = NULL;
+	if (passphrase) {
+		ptr = strchr (password_line, '\'');
+		if (ptr != NULL) {
+			ptr += 1;
+			chr = strchr (ptr, '\'');
+			if (chr != NULL) {
+				object = g_strndup (ptr, chr-ptr);
+			} else {
+				object = g_strdup (ptr);
+			}
+		}
+	} else {
+		chr = strchr (password_line, '@');
+
+		if (chr != NULL) {
+			user = g_strndup (password_line, chr - password_line);
+		}
+	}
+	if (!passphrase) {
+		server = (char *)gnome_vfs_uri_get_host_name (uri);
+		if (user == NULL) {
+			user = g_strdup ((char *)gnome_vfs_uri_get_user_name (uri));
+		}
+	}
+
+	memset (&in_args, 0, sizeof (in_args));
+	in_args.protocol = "sftp";
+	in_args.uri = gnome_vfs_uri_to_string (uri, 0);
+	in_args.object = object;
+	in_args.authtype = passphrase ? "publickey": "password";
+	in_args.domain = NULL;
+	in_args.port = gnome_vfs_uri_get_host_port (uri);
+	in_args.server = server;
+	in_args.username = user;
+	memset (&out_args, 0, sizeof (out_args));
+
+	invoked = gnome_vfs_module_callback_invoke
+		  (GNOME_VFS_MODULE_CALLBACK_FILL_AUTHENTICATION,
+		  &in_args, sizeof (in_args),
+		  &out_args, sizeof (out_args));
+	if (invoked && out_args.valid) {
+		*password_out = g_strdup (out_args.password);
+		g_free (out_args.username);
+		g_free (out_args.domain);
+		g_free (out_args.password);
+	} else {
+		*password_out = NULL;
+	}
+
+	g_free (user);
+	g_free (object);
+
+	return invoked && out_args.valid;
+}
+
+static gboolean
 invoke_full_auth (const GnomeVFSURI *uri,
 		  gboolean done_auth,
 		  const char *password_line,
-		  char **password_out)
+		  char **password_out,
+		  char **keyring_out,
+		  char **user_out,
+		  char **object_out,
+		  char **authtype_out)
 {
 	GnomeVFSModuleCallbackFullAuthenticationIn in_args;
 	GnomeVFSModuleCallbackFullAuthenticationOut out_args;
 	gboolean invoked;
 	char *user, *chr, *ptr;
-	char *object;
+	char *object, *server = NULL;
 	gboolean passphrase;
 
 	passphrase = g_str_has_prefix (password_line, "Enter passphrase for key");
@@ -880,6 +955,13 @@
 			user = g_strndup (password_line, chr - password_line);
 		}
 	}
+	if (!passphrase) {
+		server = (char *)gnome_vfs_uri_get_host_name (uri);
+		if (user == NULL) {
+			user = g_strdup ((char *)gnome_vfs_uri_get_user_name (uri));
+		}
+	}
+
 
 	memset (&in_args, 0, sizeof (in_args));
 	in_args.uri = gnome_vfs_uri_to_string (uri, 0);
@@ -887,22 +969,13 @@
 	if (done_auth) {
 		in_args.flags |= GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION_PREVIOUS_ATTEMPT_FAILED;
 	}
-	/* TODO: Support username too. A bit harder */
-
 	in_args.protocol = "sftp";
-	if (!passphrase) {
-		in_args.server = (char *)gnome_vfs_uri_get_host_name (uri);
-		if (user != NULL) {
-			in_args.username = user;
-		} else {
-			in_args.username = (char *)gnome_vfs_uri_get_user_name (uri);
-		}
-	}
 	in_args.object = object;
 	in_args.authtype = passphrase ? "publickey": "password";
-	
 	in_args.domain = NULL;
 	in_args.port = gnome_vfs_uri_get_host_port (uri);
+	in_args.server = server;
+	in_args.username = user;
 
 	memset (&out_args, 0, sizeof (out_args));
 
@@ -910,24 +983,61 @@
 		(GNOME_VFS_MODULE_CALLBACK_FULL_AUTHENTICATION,
 		 &in_args, sizeof (in_args),
 		 &out_args, sizeof (out_args));
-
 	if (invoked && !out_args.abort_auth) {
+		if (out_args.save_password) {
+			*keyring_out = g_strdup (out_args.keyring);
+			*user_out = g_strdup (user);
+			*object_out = g_strdup (object); 
+			*authtype_out = g_strdup (passphrase ? "publickey": "password");
+		}
 		*password_out = g_strdup (out_args.password);
+		g_free (out_args.username);
+		g_free (out_args.domain);
+		g_free (out_args.password);
+		g_free (out_args.keyring);
 	} else {
 		*password_out = NULL;
 	}
-	g_free (out_args.username);
-	g_free (out_args.domain);
-	g_free (out_args.password);
-	g_free (out_args.keyring);
 
-	g_free (in_args.uri);
 	g_free (user);
 	g_free (object);
 
 	return invoked && !out_args.abort_auth;
 }
 
+static void
+invoke_save_auth (const GnomeVFSURI *uri,
+	   const char *keyring,
+	   const char *user,
+	   const char *object,
+	   const char *authtype,
+	   const char *password)
+{
+	GnomeVFSModuleCallbackSaveAuthenticationIn save_in_args;
+	GnomeVFSModuleCallbackSaveAuthenticationOut save_out_args;
+
+	memset (&save_in_args, 0, sizeof (save_in_args));
+	save_in_args.uri = gnome_vfs_uri_to_string (uri, 0);
+	save_in_args.server = (char *)gnome_vfs_uri_get_host_name (uri);
+	save_in_args.port = gnome_vfs_uri_get_host_port (uri);
+	save_in_args.protocol = "sftp";
+	save_in_args.keyring = g_strdup (keyring);
+	save_in_args.username = g_strdup (user);
+	save_in_args.object = g_strdup (object);
+	save_in_args.authtype = g_strdup (authtype);
+	save_in_args.password = g_strdup (password);
+
+	memset (&save_out_args, 0, sizeof (save_out_args));
+	gnome_vfs_module_callback_invoke (GNOME_VFS_MODULE_CALLBACK_SAVE_AUTHENTICATION,
+					  &save_in_args, sizeof (save_in_args),
+					  &save_out_args, sizeof (save_out_args));
+	g_free (save_in_args.uri);
+	g_free (save_in_args.keyring);
+	g_free (save_in_args.username);
+	g_free (save_in_args.object);
+	g_free (save_in_args.password);
+}
+	
 
 /* Derived from OpenSSH, sftp.c:main */
 
@@ -942,9 +1052,15 @@
 	const gchar    *user_name;
 	gint            port;
 	guint           last_arg, i;
+	gboolean        full_auth;
 	gboolean        done_auth;
 	Buffer          msg;
 	gchar           type;
+	char *password;
+	char *keyring;
+	char *user;
+	char *object;
+	char *authtype;
 
 	GError         *error = NULL;
 
@@ -1046,6 +1162,7 @@
 					g_io_channel_get_flags (tty_channel) | G_IO_FLAG_NONBLOCK, NULL);
 	}
 	done_auth = FALSE;
+	full_auth = FALSE;
 	while (tty_fd != -1) {
 		fd_set ifds;
 		struct timeval tv;
@@ -1053,7 +1170,6 @@
 		GIOStatus io_status;
 		char buffer[1024];
 		gsize len;
-		char *password;
 		char *choices[3];
 		char *pos;
 		char *startpos;
@@ -1088,7 +1204,13 @@
 			if (g_str_has_suffix (buffer, "password: ") ||
 			    g_str_has_suffix (buffer, "Password: ") ||
 			    g_str_has_prefix (buffer, "Enter passphrase for key")) {
-				if (invoke_full_auth (uri, done_auth, buffer, &password) && password != NULL) {
+				if (!done_auth && invoke_fill_auth (uri, buffer, &password) && password != NULL) {
+					g_io_channel_write_chars (tty_channel, password, -1, &len, NULL);
+					g_io_channel_write_chars (tty_channel, "\n", 1, &len, NULL);
+					g_io_channel_flush (tty_channel, NULL);
+				} else if (invoke_full_auth (uri, done_auth, buffer, &password, &keyring, 
+							     &user, &object, &authtype) && password != NULL) {
+					full_auth = TRUE;
 					g_io_channel_write_chars (tty_channel, password, -1, &len, NULL);
 					g_io_channel_write_chars (tty_channel, "\n", 1, &len, NULL);
 					g_io_channel_flush (tty_channel, NULL);
@@ -1194,6 +1316,9 @@
 		res = GNOME_VFS_ERROR_PROTOCOL_ERROR;
 	} else {
 		/* Everything's A-OK. Set up the connection and go */
+		if (full_auth == TRUE) {
+			invoke_save_auth (uri, keyring, user, object, authtype, password);
+		}
 
 		if (!g_thread_supported ()) g_thread_init (NULL);
 
@@ -1218,6 +1343,12 @@
 
  bail:
 	buffer_free (&msg);
+
+	g_free (password);
+	g_free (keyring);
+	g_free (user);
+	g_free (object);
+	g_free (authtype);
 
 	if (res != GNOME_VFS_OK) {
 		close (in_fd);


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