[gnome-disk-utility] For now, rely on $SSH_ASKPASS for user interaction when authentication



commit ceb56b654a9043ebf3694a040c88acfdefc57021
Author: David Zeuthen <davidz redhat com>
Date:   Sat Dec 5 17:10:35 2009 -0500

    For now, rely on $SSH_ASKPASS for user interaction when authentication
    
    Might be we just want to do this.

 src/gdu/gdu-pool.c         |   72 ++++++++++++++++++++---------------
 src/gdu/gdu-pool.h         |    2 +-
 src/gdu/gdu-ssh-bridge.c   |   90 +++++++++++++++++++++++++++++--------------
 src/gdu/gdu-ssh-bridge.h   |    1 -
 src/palimpsest/gdu-main.c  |    5 +--
 src/palimpsest/gdu-shell.c |   22 +++++++----
 src/palimpsest/gdu-shell.h |    3 +-
 7 files changed, 120 insertions(+), 75 deletions(-)
---
diff --git a/src/gdu/gdu-pool.c b/src/gdu/gdu-pool.c
index 3aef9e0..f9db8ef 100644
--- a/src/gdu/gdu-pool.c
+++ b/src/gdu/gdu-pool.c
@@ -41,6 +41,7 @@
 #include "gdu-private.h"
 
 #include "gdu-ssh-bridge.h"
+#include "gdu-error.h"
 
 #include "udisks-daemon-glue.h"
 #include "gdu-marshal.h"
@@ -107,8 +108,10 @@ G_DEFINE_TYPE (GduPool, gdu_pool, G_TYPE_OBJECT);
 static void
 gdu_pool_finalize (GduPool *pool)
 {
-        dbus_g_connection_unref (pool->priv->bus);
-        g_object_unref (pool->priv->proxy);
+        if (pool->priv->bus != NULL)
+                dbus_g_connection_unref (pool->priv->bus);
+        if (pool->priv->proxy != NULL)
+                g_object_unref (pool->priv->proxy);
 
         g_free (pool->priv->daemon_version);
 
@@ -1663,7 +1666,17 @@ out:
 GduPool *
 gdu_pool_new (void)
 {
-        return gdu_pool_new_for_address (NULL, NULL);
+        GduPool *pool;
+        GError *error;
+
+        error = NULL;
+        pool = gdu_pool_new_for_address (NULL, &error);
+        if (pool != NULL) {
+                g_printerr ("Error constructing pool: %s\n", error->message);
+                g_error_free (error);
+        }
+
+        return pool;
 }
 
 DBusGConnection *
@@ -1674,7 +1687,7 @@ _gdu_pool_get_connection (GduPool *pool)
 
 GduPool *
 gdu_pool_new_for_address (const gchar     *ssh_address,
-                          GMountOperation *connect_operation)
+                          GError         **error)
 {
         int n;
         GPtrArray *devices;
@@ -1682,25 +1695,20 @@ gdu_pool_new_for_address (const gchar     *ssh_address,
         GPtrArray *expanders;
         GPtrArray *ports;
         GduPool *pool;
-        GError *error;
+        GError *local_error;
+
+        local_error = NULL;
 
         pool = GDU_POOL (g_object_new (GDU_TYPE_POOL, NULL));
 
-        error = NULL;
         if (ssh_address == NULL) {
-                pool->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+                pool->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, error);
                 if (pool->priv->bus == NULL) {
-                        g_warning ("Error connecting to system bus: %s", error->message);
-                        g_error_free (error);
                         goto error;
                 }
         } else {
-                pool->priv->bus = _gdu_ssh_bridge_connect (pool, ssh_address, connect_operation, &error);
+                pool->priv->bus = _gdu_ssh_bridge_connect (pool, ssh_address, error);
                 if (pool->priv->bus == NULL) {
-                        g_warning ("Error connecting to ssh address `%s': %s",
-                                   ssh_address,
-                                   error->message);
-                        g_error_free (error);
                         goto error;
                 }
         }
@@ -1779,10 +1787,11 @@ gdu_pool_new_for_address (const gchar     *ssh_address,
                                      G_CALLBACK (port_changed_signal_handler), pool, NULL);
 
         /* prime the list of devices */
-        error = NULL;
-        if (!org_freedesktop_UDisks_enumerate_devices (pool->priv->proxy, &devices, &error)) {
-                g_warning ("Couldn't enumerate devices: %s", error->message);
-                g_error_free (error);
+        if (!org_freedesktop_UDisks_enumerate_devices (pool->priv->proxy, &devices, &local_error)) {
+                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                             _("Error enumerating devices: %s"),
+                             local_error->message);
+                g_error_free (local_error);
                 goto error;
         }
 
@@ -1804,10 +1813,11 @@ gdu_pool_new_for_address (const gchar     *ssh_address,
         g_ptr_array_free (devices, TRUE);
 
         /* prime the list of adapters */
-        error = NULL;
-        if (!org_freedesktop_UDisks_enumerate_adapters (pool->priv->proxy, &adapters, &error)) {
-                g_warning ("Couldn't enumerate adapters: %s", error->message);
-                g_error_free (error);
+        if (!org_freedesktop_UDisks_enumerate_adapters (pool->priv->proxy, &adapters, &local_error)) {
+                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                             _("Error enumerating adapters: %s"),
+                             local_error->message);
+                g_error_free (local_error);
                 goto error;
         }
         for (n = 0; n < (int) adapters->len; n++) {
@@ -1826,10 +1836,11 @@ gdu_pool_new_for_address (const gchar     *ssh_address,
         g_ptr_array_free (adapters, TRUE);
 
         /* prime the list of expanders */
-        error = NULL;
-        if (!org_freedesktop_UDisks_enumerate_expanders (pool->priv->proxy, &expanders, &error)) {
-                g_warning ("Couldn't enumerate expanders: %s", error->message);
-                g_error_free (error);
+        if (!org_freedesktop_UDisks_enumerate_expanders (pool->priv->proxy, &expanders, &local_error)) {
+                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                             _("Error enumerating expanders: %s"),
+                             local_error->message);
+                g_error_free (local_error);
                 goto error;
         }
         for (n = 0; n < (int) expanders->len; n++) {
@@ -1848,10 +1859,11 @@ gdu_pool_new_for_address (const gchar     *ssh_address,
         g_ptr_array_free (expanders, TRUE);
 
         /* prime the list of ports */
-        error = NULL;
-        if (!org_freedesktop_UDisks_enumerate_ports (pool->priv->proxy, &ports, &error)) {
-                g_warning ("Couldn't enumerate ports: %s", error->message);
-                g_error_free (error);
+        if (!org_freedesktop_UDisks_enumerate_ports (pool->priv->proxy, &ports, &local_error)) {
+                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                             _("Error enumerating ports: %s"),
+                             local_error->message);
+                g_error_free (local_error);
                 goto error;
         }
         for (n = 0; n < (int) ports->len; n++) {
diff --git a/src/gdu/gdu-pool.h b/src/gdu/gdu-pool.h
index 5127afc..1199487 100644
--- a/src/gdu/gdu-pool.h
+++ b/src/gdu/gdu-pool.h
@@ -80,7 +80,7 @@ struct _GduPoolClass
 GType       gdu_pool_get_type           (void);
 GduPool    *gdu_pool_new                (void);
 GduPool    *gdu_pool_new_for_address    (const gchar     *ssh_address,
-                                         GMountOperation *connect_operation);
+                                         GError         **error);
 
 char       *gdu_pool_get_daemon_version (GduPool *pool);
 gboolean    gdu_pool_is_daemon_inhibited (GduPool *pool);
diff --git a/src/gdu/gdu-ssh-bridge.c b/src/gdu/gdu-ssh-bridge.c
index b9f5fc7..da8121e 100644
--- a/src/gdu/gdu-ssh-bridge.c
+++ b/src/gdu/gdu-ssh-bridge.c
@@ -47,6 +47,9 @@
  *
  *  Client can now use the D-Bus connection - Server is guaranteed to forward method calls and signals
  *  to and from the org.freedesktop.UDisks service running on Server
+ *
+ *  The reason we pass have an authorization SECRET is that otherwise
+ *  malicious users on both the Client and Server may interfere.
  */
 
 typedef struct {
@@ -157,10 +160,27 @@ on_new_connection (DBusServer     *server,
         ;
 }
 
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+static void
+child_setup (gpointer user_data)
+{
+        gint fd;
+
+        /* lose controlling terminal - this forces $SSH_ASKPASS to be used for authentication */
+        if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
+                ioctl(fd, TIOCNOTTY, 0); /* lose controlling terminal */
+                close(fd);
+        }
+}
+
 DBusGConnection *
 _gdu_ssh_bridge_connect (GduPool          *pool,
                          const gchar      *ssh_address,
-                         GMountOperation  *connect_operation,
                          GError          **error)
 {
         BridgeData *data;
@@ -284,7 +304,7 @@ _gdu_ssh_bridge_connect (GduPool          *pool,
                                        ssh_argv,
                                        NULL,
                                        G_SPAWN_SEARCH_PATH,
-                                       NULL,
+                                       child_setup,
                                        NULL,
                                        &ssh_pid,
                                        &stdin_fd,
@@ -310,28 +330,38 @@ _gdu_ssh_bridge_connect (GduPool          *pool,
         g_object_unref (stdout_stream);
         g_object_unref (stderr_stream);
 
-        /* Read and parse the remote port number */
-        s = g_data_input_stream_read_line (stderr_data_stream,
-                                           NULL, /* gsize *length */
-                                           NULL,
-                                           &local_error);
-        if (s == NULL) {
-                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
-                             _("Error reading output for reverse tunnel setup on host `%s': %s"),
-                             ssh_address, local_error->message);
-                g_error_free (local_error);
-                goto out;
-        }
-        if (sscanf (s, "Allocated port %d for remote forward to", &remote_port) != 1) {
-                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
-                             _("Unexpected output from ssh: "
-                               "Expected `Allocated port <number> for remote forward to' but got `%s'"),
-                             s);
-                g_free (s);
-                goto out;
+        while (TRUE) {
+                /* Read and parse the remote port number */
+                s = g_data_input_stream_read_line (stderr_data_stream,
+                                                   NULL, /* gsize *length */
+                                                   NULL,
+                                                   &local_error);
+                if (s == NULL) {
+                        if (local_error != NULL) {
+                                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                                             _("Error reading stderr output from host `%s': %s"),
+                                             ssh_address, local_error->message);
+                                g_error_free (local_error);
+                        } else {
+                                /* This happens if ssh exits due to e.g. permission denied */
+                                g_set_error (error, GDU_ERROR, GDU_ERROR_PERMISSION_DENIED,
+                                             _("Failed to log into host `%s'"),
+                                             ssh_address);
+                        }
+                        goto out;
+                } else if (strlen (s) == 0) {
+                        g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                                     _("Unexpected blank line in stderr output from host `%s'"),
+                                     ssh_address);
+                        g_free (s);
+                        goto out;
+                } else if (sscanf (s, "Allocated port %d for remote forward to", &remote_port) == 1) {
+                        g_free (s);
+                        break;
+                }
         }
+
         //g_print ("Yay, remote port is %d (forwarding to local port %d)\n", remote_port, local_port);
-        g_free (s);
 
         /* Now start the bridge - the udisks-tcp-bridge program will connect to the remote port
          * which is forwarded to the local port by ssh
@@ -342,7 +372,7 @@ _gdu_ssh_bridge_connect (GduPool          *pool,
                                               NULL,
                                               &local_error)) {
                 g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
-                             _("Error executing `%s' on host `%s': %s"),
+                             _("Error sending `%s' to host `%s': %s"),
                              s, ssh_address, local_error->message);
                 g_error_free (local_error);
                 g_free (s);
@@ -358,14 +388,14 @@ _gdu_ssh_bridge_connect (GduPool          *pool,
                                            &local_error);
         if (s == NULL) {
                 g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
-                             _("Error reading output from udisks-tcp-bridge program on host `%s': %s"),
+                             _("Error reading stderr output from host `%s': %s"),
                              ssh_address, local_error->message);
                 g_error_free (local_error);
                 goto out;
         }
         if (g_strcmp0 (s, "udisks-tcp-bridge: Waiting for secret") != 0) {
                 g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
-                             _("Unexpected output from udisks-tcp-bridge program on host `%s': "
+                             _("Unexpected stderr output from from host `%s': "
                                "Expected `udisks-tcp-bridge: Waiting for secret' but got `%s'"),
                              ssh_address, s);
                 g_free (s);
@@ -400,14 +430,14 @@ _gdu_ssh_bridge_connect (GduPool          *pool,
                                            &local_error);
         if (s == NULL) {
                 g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
-                             _("Error reading output from udisks-tcp-bridge program on host `%s': %s"),
+                             _("Error reading stderr from host `%s': %s"),
                              ssh_address, local_error->message);
                 g_error_free (local_error);
                 goto out;
         }
         if (sscanf (s, "udisks-tcp-bridge: Attempting to connect to port %d", &remote_port) != 1) {
                 g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
-                             _("Unexpected output from udisks-tcp-bridge program on host `%s': "
+                             _("Unexpected stderr output from host `%s': "
                                "Expected `udisks-tcp-bridge: Attempting to connect to port %d' but got `%s'"),
                              ssh_address, remote_port, s);
                 g_free (s);
@@ -415,7 +445,7 @@ _gdu_ssh_bridge_connect (GduPool          *pool,
         }
         g_free (s);
 
-        /* Wait for connection and authorization */
+        /* Wait for D-Bus connection and authorization */
         data->loop = g_main_loop_new (NULL, FALSE);
         g_main_loop_run (data->loop);
 
@@ -440,8 +470,10 @@ _gdu_ssh_bridge_connect (GduPool          *pool,
  out:
         if (data != NULL)
                 bridge_data_free (data);
-        if (server != NULL)
+        if (server != NULL) {
+                dbus_server_disconnect (server);
                 dbus_server_unref (server);
+        }
         if (stdin_data_stream != NULL)
                 g_object_unref (stdin_data_stream);
         if (stdout_data_stream != NULL)
diff --git a/src/gdu/gdu-ssh-bridge.h b/src/gdu/gdu-ssh-bridge.h
index 11c336b..30f7361 100644
--- a/src/gdu/gdu-ssh-bridge.h
+++ b/src/gdu/gdu-ssh-bridge.h
@@ -31,7 +31,6 @@
 
 DBusGConnection * _gdu_ssh_bridge_connect (GduPool          *pool,
                                            const gchar      *ssh_address,
-                                           GMountOperation  *connect_operation,
                                            GError          **error);
 
 #endif /* __GDU_SSH_BRIDGE_H */
diff --git a/src/palimpsest/gdu-main.c b/src/palimpsest/gdu-main.c
index 2b1d1fe..9a33e5a 100644
--- a/src/palimpsest/gdu-main.c
+++ b/src/palimpsest/gdu-main.c
@@ -179,10 +179,7 @@ main (int argc, char **argv)
                         return 1;
         }
 
-        GMountOperation *connect_operation;
-        connect_operation = gtk_mount_operation_new (NULL);
-        shell = gdu_shell_new (dbus_address, connect_operation);
-        g_object_unref (connect_operation);
+        shell = gdu_shell_new (dbus_address);
 
         g_signal_connect (unique_app, "message-received",
                           G_CALLBACK (message_received), shell);
diff --git a/src/palimpsest/gdu-shell.c b/src/palimpsest/gdu-shell.c
index 0539e58..f46ae2b 100644
--- a/src/palimpsest/gdu-shell.c
+++ b/src/palimpsest/gdu-shell.c
@@ -87,8 +87,7 @@ gdu_shell_class_init (GduShellClass *klass)
         g_type_class_add_private (klass, sizeof (GduShellPrivate));
 }
 
-static void create_window (GduShell        *shell,
-                           GMountOperation *connect_operation);
+static void create_window (GduShell        *shell);
 
 static void
 gdu_shell_init (GduShell *shell)
@@ -97,13 +96,12 @@ gdu_shell_init (GduShell *shell)
 }
 
 GduShell *
-gdu_shell_new (const gchar     *ssh_address,
-               GMountOperation *connect_operation)
+gdu_shell_new (const gchar *ssh_address)
 {
         GduShell *shell;
         shell = GDU_SHELL (g_object_new (GDU_TYPE_SHELL, NULL));
         shell->priv->ssh_address = g_strdup (ssh_address);
-        create_window (shell, connect_operation);
+        create_window (shell);
         return shell;
 }
 
@@ -1659,8 +1657,7 @@ gdu_shell_raise_error (GduShell       *shell,
 }
 
 static void
-create_window (GduShell *shell,
-               GMountOperation *connect_operation)
+create_window (GduShell *shell)
 {
         GtkWidget *vbox;
         GtkWidget *vbox1;
@@ -1673,8 +1670,17 @@ create_window (GduShell *shell,
         GtkWidget *label;
         GduPoolTreeModel *model;
         GtkTreeViewColumn *column;
+        GError *error;
 
-        shell->priv->pool = gdu_pool_new_for_address (shell->priv->ssh_address, connect_operation);
+        error = NULL;
+        shell->priv->pool = gdu_pool_new_for_address (shell->priv->ssh_address, &error);
+        if (error != NULL) {
+                g_printerr ("Error connecting to `%s': %s",
+                            shell->priv->ssh_address,
+                            error->message);
+                g_error_free (error);
+                g_critical ("Exiting");
+        }
 
         shell->priv->app_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
         gtk_window_set_resizable (GTK_WINDOW (shell->priv->app_window), TRUE);
diff --git a/src/palimpsest/gdu-shell.h b/src/palimpsest/gdu-shell.h
index f281227..5e4c594 100644
--- a/src/palimpsest/gdu-shell.h
+++ b/src/palimpsest/gdu-shell.h
@@ -54,8 +54,7 @@ struct _GduShellClass
 };
 
 GType           gdu_shell_get_type                 (void);
-GduShell       *gdu_shell_new                      (const char      *ssh_address,
-                                                    GMountOperation *connect_operation);
+GduShell       *gdu_shell_new                      (const char      *ssh_address);
 GtkWidget      *gdu_shell_get_toplevel             (GduShell       *shell);
 GduPool        *gdu_shell_get_pool                 (GduShell       *shell);
 void            gdu_shell_update                   (GduShell       *shell);



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