Re: patches for ssh



On Tue, 2003-02-11 at 09:51, Bastien Nocera wrote:
> Hello,
> 
> A small patch against HEAD that:
> - Give a "login failed" error when there is no key access setup to
> access some machine (dependant on OpenSSH, see comment)
> - Use port information from the URI to connect (fixes a FIXME in the
> code)
> - redirect ssh:/// to ssh://localhost/
> 
> And I couldn't reproduce that bug (could I close it?):
> http://bugzilla.gnome.org/show_bug.cgi?id=87668
> 
> Cheers
> 
> PS: CC: me as I'm not on this list

Updated the patch to wait a little while for the completion of the ssh
command before trying to kill it. On my network, it was killing ssh too
rapidly for the command to complete, hence things like
"do_make_directory" not working properly.

Patch attached

-- 
/Bastien Nocera
http://hadess.net

#2  0x4205a2cc in printf ("Oh my %s\n", preferred_deity) from
/lib/i686/libc.so.6 printf ("Oh my %s\n", preferred_deity);
Segmentation fault
Index: ssh-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/ssh-method.c,v
retrieving revision 1.14
diff -u -r1.14 ssh-method.c
--- ssh-method.c	8 Nov 2002 10:35:47 -0000	1.14
+++ ssh-method.c	11 Feb 2003 13:34:44 -0000
@@ -37,8 +37,10 @@
 #include <unistd.h>
 #include <signal.h>
 #include <sys/signal.h>
+#include <fcntl.h>
 
-#define LINE_LENGTH 4096 /* max line length we'll grok */
+#define LINE_LENGTH 4096	/* max line length we'll grok */
+#define SLEEP_TIME 300000	/* time we'll wait for the process to finish */
 
 typedef struct {
 	GnomeVFSMethodHandle method_handle;
@@ -54,6 +56,10 @@
 	GnomeVFSFileInfoOptions info_opts;
 } SshHandle;
 
+static GnomeVFSResult ssh_read_error	(int error_fd,
+					 gpointer buffer,
+					 GnomeVFSFileSize num_bytes,
+					 GnomeVFSFileSize *bytes_read);
 static GnomeVFSResult do_open           (GnomeVFSMethod *method,
 				         GnomeVFSMethodHandle **method_handle,
 				         GnomeVFSURI *uri,
@@ -156,50 +162,77 @@
 {
 	char ** argv;
 	SshHandle *handle;
-	char *command_line;
-	const gchar *username;
-	int argc;
+	char *command_line, *host_port;
+	const gchar *username, *hostname;
+	int argc, error_fd;
 	GError *gerror = NULL;
+	GnomeVFSFileSize bytes_read;
+	char buffer[LINE_LENGTH];
+
+	/* We do support ssh:/// as ssh://localhost/ */
+	hostname = gnome_vfs_uri_get_host_name (uri);
+	if (hostname == NULL) {
+		hostname = "localhost";
+	}
 
 	username = gnome_vfs_uri_get_user_name(uri);
 	if (username == NULL) {
 		username = g_get_user_name();
 	}
-	
+
+	host_port = g_strdup_printf("%d", gnome_vfs_uri_get_host_port(uri) ?
+			gnome_vfs_uri_get_host_port(uri) : 22);
+
 	command_line  = g_strconcat ("ssh -oBatchMode=yes -x -l ", 
 				     username,
-				     " ", gnome_vfs_uri_get_host_name (uri),
+				     " -p ", host_port,
+				     " ", hostname,
 				     " ", "\"LC_ALL=C;", command,"\"",
 				     NULL);
+	g_free (host_port);
 
 	g_shell_parse_argv (command_line, &argc, &argv, &gerror);
+
 	g_free (command_line);
 	if (gerror) {
 		g_warning (gerror->message);
 		return GNOME_VFS_ERROR_BAD_PARAMETERS;
 	}
 
-
-	/* fixme: handle other ports */
 	handle = g_new0 (SshHandle, 1);
 	handle->uri = uri;
 
 	g_spawn_async_with_pipes (NULL, argv, NULL, 
-				  G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
+				  G_SPAWN_SEARCH_PATH,
 				  NULL, NULL,
 				  &handle->pid, &handle->write_fd, &handle->read_fd,
-				  NULL, &gerror);
+				  &error_fd, &gerror);
 	g_strfreev (argv);
 
 	if (gerror) {
 		g_warning (gerror->message);
 		g_free (handle);
+		return GNOME_VFS_ERROR_GENERIC;
 	}
 
 	gnome_vfs_uri_ref (handle->uri);
 
 	*handle_return = handle;
 
+	/* You can add more error checking here */
+	memset (buffer, '\0', LINE_LENGTH);
+	ssh_read_error (error_fd, &buffer, LINE_LENGTH, &bytes_read);
+
+	if (bytes_read != 0) {
+		if (strncmp ("Permission denied", buffer,
+					strlen("Permission denied")) == 0) {
+			close (error_fd);
+			return GNOME_VFS_ERROR_LOGIN_FAILED;
+		}
+	}
+
+	close (error_fd);
+
 	return GNOME_VFS_OK;
 }
 
@@ -236,6 +269,28 @@
 }
 
 static GnomeVFSResult
+ssh_read_error (int error_fd,
+		gpointer buffer,
+		GnomeVFSFileSize num_bytes,
+		GnomeVFSFileSize *bytes_read)
+{
+	GnomeVFSFileSize my_read;
+
+	/* Make sure we're not blocking on read */
+	fcntl (error_fd, F_SETFL, O_NONBLOCK);
+	my_read = (GnomeVFSFileSize) read (error_fd, buffer,
+			(size_t) num_bytes);
+
+	if (my_read == -1) {
+		return gnome_vfs_result_from_errno ();
+	}
+
+	*bytes_read = my_read;
+
+	return GNOME_VFS_OK;
+}
+
+static GnomeVFSResult
 ssh_write (SshHandle *handle,
 	   gconstpointer buffer,
 	   GnomeVFSFileSize num_bytes,
@@ -263,6 +318,19 @@
 	return GNOME_VFS_OK;
 }
 
+static GnomeVFSResult
+ssh_wait_and_destroy (SshHandle *handle)
+{
+	int i;
+
+	for (i = 0; i < 10 && kill (handle->pid, 0) != -1; i++) {
+		usleep (SLEEP_TIME);
+	}
+
+	return ssh_destroy (handle);
+}
+
+
 #if 0
 static GnomeVFSResult
 ssh_send (SshHandle *handle,
@@ -301,7 +369,7 @@
 						  G_DIR_SEPARATOR_S);
 		quoted_name = g_shell_quote (name);
 		g_free (name);
-		
+
 		cmd = g_strdup_printf ("cat %s", quoted_name);
 		result = ssh_connect (&handle, uri, cmd);
 		g_free (cmd);
@@ -312,7 +380,7 @@
 	} else {
 		return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
 	}
-	
+
 	handle->open_mode = mode;
 	handle->type = SSH_FILE;
 	*method_handle = (GnomeVFSMethodHandle *)handle;
@@ -320,7 +388,7 @@
 	return GNOME_VFS_OK;
 }
 
-static GnomeVFSResult   
+static GnomeVFSResult
 do_create (GnomeVFSMethod *method,
 	   GnomeVFSMethodHandle **method_handle,
 	   GnomeVFSURI *uri,
@@ -666,7 +734,7 @@
 		return result;
 	}
 
-	ssh_destroy (handle);
+	ssh_wait_and_destroy (handle);
 
 	return result;
 }
@@ -697,7 +765,7 @@
 		return result;
 	}
 
-	ssh_destroy (handle);
+	ssh_wait_and_destroy (handle);
 
 	return result;
 }
@@ -728,7 +796,7 @@
 		return result;
 	}
 
-	ssh_destroy (handle);
+	ssh_wait_and_destroy (handle);
 
 	return result;
 }
@@ -815,7 +883,7 @@
 }
 #endif
 
-gboolean 
+gboolean
 do_is_local (GnomeVFSMethod *method, const GnomeVFSURI *uri)
 {
         return FALSE;


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