[gnome-disk-utility] Rework remote connection handling - in particular tunnel it over ssh



commit 4e8567698cd3a38b93bf7e9e2fa50d0519b3f1a4
Author: David Zeuthen <davidz redhat com>
Date:   Sat Dec 5 15:24:40 2009 -0500

    Rework remote connection handling - in particular tunnel it over ssh
    
    This feature is almost done - we need to use the passed
    connection_operation though.

 src/gdu/Makefile.am        |    1 +
 src/gdu/gdu-pool.c         |   17 +-
 src/gdu/gdu-pool.h         |    3 +-
 src/gdu/gdu-ssh-bridge.c   |  455 ++++++++++++++++++++++++++++++++++++++++++++
 src/gdu/gdu-ssh-bridge.h   |   37 ++++
 src/palimpsest/gdu-main.c  |    5 +-
 src/palimpsest/gdu-shell.c |   19 +-
 src/palimpsest/gdu-shell.h |    3 +-
 8 files changed, 522 insertions(+), 18 deletions(-)
---
diff --git a/src/gdu/Makefile.am b/src/gdu/Makefile.am
index e3d1ed8..690b854 100644
--- a/src/gdu/Makefile.am
+++ b/src/gdu/Makefile.am
@@ -74,6 +74,7 @@ libgdu_la_SOURCES =                                					\
 	gdu-process.c				gdu-process.h				\
 	gdu-hub.c				gdu-hub.h				\
 						gdu-private.h				\
+	gdu-ssh-bridge.c			gdu-ssh-bridge.h			\
 	$(BUILT_SOURCES)								\
 	$(NULL)
 
diff --git a/src/gdu/gdu-pool.c b/src/gdu/gdu-pool.c
index 79ffbfe..3aef9e0 100644
--- a/src/gdu/gdu-pool.c
+++ b/src/gdu/gdu-pool.c
@@ -40,6 +40,8 @@
 #include "gdu-known-filesystem.h"
 #include "gdu-private.h"
 
+#include "gdu-ssh-bridge.h"
+
 #include "udisks-daemon-glue.h"
 #include "gdu-marshal.h"
 
@@ -1661,7 +1663,7 @@ out:
 GduPool *
 gdu_pool_new (void)
 {
-        return gdu_pool_new_for_address (NULL);
+        return gdu_pool_new_for_address (NULL, NULL);
 }
 
 DBusGConnection *
@@ -1671,7 +1673,8 @@ _gdu_pool_get_connection (GduPool *pool)
 }
 
 GduPool *
-gdu_pool_new_for_address (const gchar *dbus_address)
+gdu_pool_new_for_address (const gchar     *ssh_address,
+                          GMountOperation *connect_operation)
 {
         int n;
         GPtrArray *devices;
@@ -1684,18 +1687,18 @@ gdu_pool_new_for_address (const gchar *dbus_address)
         pool = GDU_POOL (g_object_new (GDU_TYPE_POOL, NULL));
 
         error = NULL;
-        if (dbus_address == NULL) {
+        if (ssh_address == NULL) {
                 pool->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
                 if (pool->priv->bus == NULL) {
-                        g_warning ("Couldn't connect to system bus: %s", error->message);
+                        g_warning ("Error connecting to system bus: %s", error->message);
                         g_error_free (error);
                         goto error;
                 }
         } else {
-                pool->priv->bus = dbus_g_connection_open (dbus_address, &error);
+                pool->priv->bus = _gdu_ssh_bridge_connect (pool, ssh_address, connect_operation, &error);
                 if (pool->priv->bus == NULL) {
-                        g_warning ("Couldn't connect to address `%s': %s",
-                                   dbus_address,
+                        g_warning ("Error connecting to ssh address `%s': %s",
+                                   ssh_address,
                                    error->message);
                         g_error_free (error);
                         goto error;
diff --git a/src/gdu/gdu-pool.h b/src/gdu/gdu-pool.h
index 5c78542..5127afc 100644
--- a/src/gdu/gdu-pool.h
+++ b/src/gdu/gdu-pool.h
@@ -79,7 +79,8 @@ struct _GduPoolClass
 
 GType       gdu_pool_get_type           (void);
 GduPool    *gdu_pool_new                (void);
-GduPool    *gdu_pool_new_for_address    (const gchar *dbus_address);
+GduPool    *gdu_pool_new_for_address    (const gchar     *ssh_address,
+                                         GMountOperation *connect_operation);
 
 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
new file mode 100644
index 0000000..b9f5fc7
--- /dev/null
+++ b/src/gdu/gdu-ssh-bridge.c
@@ -0,0 +1,455 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 David Zeuthen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#include <stdio.h>
+#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "gdu-ssh-bridge.h"
+#include "gdu-error.h"
+
+/* Here's how it works
+ *
+ * - Client sets up a DBusServer on port LOCAL_PORT
+ *   - we try a number of ports (in the 9000 to 10000 range) until this succeed
+ * - Client creates a big random number SECRET
+ * - Client creates a ssh connection to Server requesting a port-forward to Client:LOCAL_PORT
+ *   - using -R 0:localhost:LOCAL_PORT
+ * - Client parses REMOTE_PORT from "Allocated port <NUM> for remote forward to localhost:LOCAL_PORT"
+ * - Client launches "udisks-tcp-bridge -p REMOTE" on Server and then writes SECRET and then a newline
+ * - Server (effectively, ie. through the bridge) connects to Client:LOCAL_PORT
+ * - Server invokes the org.freedesktop.UDisks.Client.Authorize with the SECRET string
+ * - Client checks SECRET
+ *   - if it doesn't check out, and error is returned and Server is disconnected
+ *   - otherwise the method returns
+ *
+ *  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
+ */
+
+typedef struct {
+        gchar *secret;
+        GMainLoop *loop;
+        DBusConnection *server_connection;
+        gboolean authorized;
+
+        gchar *error_message;
+} BridgeData;
+
+static DBusHandlerResult connection_filter_func (DBusConnection  *connection,
+                                                 DBusMessage     *message,
+                                                 void            *user_data);
+
+static void
+bridge_data_free (BridgeData *data)
+{
+        if (data->secret != NULL)
+                memset (data->secret, '\0', strlen (data->secret));
+        g_free (data->secret);
+        g_free (data->error_message);
+        if (data->loop != NULL)
+                g_main_loop_unref (data->loop);
+        if (data->server_connection != NULL) {
+                dbus_connection_remove_filter (data->server_connection,
+                                               connection_filter_func,
+                                               data);
+                dbus_connection_unref (data->server_connection);
+        }
+        g_free (data);
+}
+
+static DBusHandlerResult
+connection_filter_func (DBusConnection  *connection,
+                        DBusMessage     *message,
+                        void            *user_data)
+{
+        BridgeData *data = user_data;
+
+        //g_print ("Filter func!\n");
+
+        if (dbus_message_is_method_call (message, "org.freedesktop.UDisks.Client", "Authorize") &&
+            dbus_message_has_path (message, "/org/freedesktop/UDisks/Client")) {
+                const gchar *secret;
+                DBusMessage *reply;
+                DBusError dbus_error;
+
+                dbus_error_init (&dbus_error);
+                if (!dbus_message_get_args (message, &dbus_error, DBUS_TYPE_STRING, &secret, DBUS_TYPE_INVALID)) {
+                        reply = dbus_message_new_error (message,
+                                                        "org.freedesktop.UDisks.Error.PermissionDenied",
+                                                        "Error extracting authorization secret");
+                        dbus_error_free (&dbus_error);
+                        data->error_message = g_strdup ("No (or malformed) authorization secret included in the Authorize() method call!");
+                } else if (g_strcmp0 (secret, data->secret) != 0) {
+                        reply = dbus_message_new_error (message,
+                                                        "org.freedesktop.UDisks.Error.PermissionDenied",
+                                                        "Authorization secret does not match");
+                        data->error_message = g_strdup ("Authorization secret passed from server does not match what we expected");
+                } else {
+                        data->authorized = TRUE;
+                        reply = dbus_message_new_method_return (message);
+                }
+                dbus_connection_send (connection, reply, NULL);
+                dbus_message_unref (reply);
+        } else {
+                data->error_message = g_strdup_printf ("Expected a method call Authorize() on interface "
+                                                       "org.freedesktop.UDisks.Client  on the object "
+                                                       "/org/freedesktop/UDisks/Client but instead got a message of "
+                                                       "type=%d, path=`%s', interface=`%s' and member=`%s'.\n",
+                                                       dbus_message_get_type (message),
+                                                       dbus_message_get_path (message),
+                                                       dbus_message_get_interface (message),
+                                                       dbus_message_get_member (message));
+        }
+
+        g_main_loop_quit (data->loop);
+
+        return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+on_new_connection (DBusServer     *server,
+                   DBusConnection *new_connection,
+                   void           *user_data)
+{
+        BridgeData *data = user_data;
+
+        if (data->server_connection != NULL) {
+                g_printerr ("Someone tried to connect but we already have a connection.\n");
+                goto out;
+        }
+
+        dbus_connection_set_allow_anonymous (new_connection, TRUE);
+        dbus_connection_setup_with_g_main (new_connection, NULL);
+        dbus_connection_ref (new_connection);
+        data->server_connection = new_connection;
+
+        //g_print ("We have a client - waiting for authorization\n");
+
+        /* Wait for client to authorize */
+        dbus_connection_add_filter (data->server_connection,
+                                    connection_filter_func,
+                                    data,
+                                    NULL);
+ out:
+        ;
+}
+
+DBusGConnection *
+_gdu_ssh_bridge_connect (GduPool          *pool,
+                         const gchar      *ssh_address,
+                         GMountOperation  *connect_operation,
+                         GError          **error)
+{
+        BridgeData *data;
+        DBusGConnection *ret;
+        GError *local_error;
+        gchar *command_line;
+        gint ssh_argc;
+        gchar **ssh_argv;
+        GPid ssh_pid;
+        gchar *dbus_address;
+        gint stdin_fd;
+        gint stdout_fd;
+        gint stderr_fd;
+        gint local_port;
+        gint remote_port;
+        GOutputStream *stdin_stream;
+        GInputStream *stdout_stream;
+        GInputStream *stderr_stream;
+        GDataOutputStream *stdin_data_stream;
+        GDataInputStream *stdout_data_stream;
+        GDataInputStream *stderr_data_stream;
+        gchar *s;
+        DBusError dbus_error;
+        DBusServer *server;
+        const gchar *auth_mechanisms[] = {"ANONYMOUS", NULL};
+        GString *str;
+        guint n;
+
+        local_error = NULL;
+
+        ret = NULL;
+
+        data = NULL;
+        ssh_argv = NULL;
+        command_line = NULL;
+        dbus_address = NULL;
+        server = NULL;
+        stdin_data_stream = NULL;
+        stdout_data_stream = NULL;
+        stderr_data_stream = NULL;
+
+        data = g_new0 (BridgeData, 1);
+        str = g_string_new (NULL);
+        for (n = 0; n < 32; n++) {
+                guint32 r = g_random_int ();
+                g_string_append_printf (str, "%08x", r);
+        }
+        data->secret = g_string_free (str, FALSE);
+
+        /* Create and start the local DBusServer */
+        for (local_port = 9000; local_port < 10000; local_port++) {
+                s = g_strdup_printf ("tcp:host=localhost,port=%d", local_port);
+                dbus_error_init (&dbus_error);
+                server = dbus_server_listen (s, &dbus_error);
+                g_free (s);
+                if (server == NULL) {
+                        if (g_strcmp0 (dbus_error.name, "org.freedesktop.DBus.Error.AddressInUse") == 0) {
+                                continue;
+                        } else {
+                                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                                             _("Error listening to address `localhost:%d': %s: %s\n"),
+                                             local_port,
+                                             dbus_error.name,
+                                             dbus_error.message);
+                                dbus_error_free (&dbus_error);
+                                goto out;
+                        }
+                } else {
+                        break;
+                }
+        }
+        if (server == NULL) {
+                g_set_error (error,
+                             GDU_ERROR,
+                             GDU_ERROR_FAILED,
+                             _("Error creating a local TCP server, tried binding to ports 9000-10000 on localhost"));
+                dbus_error_free (&dbus_error);
+                goto out;
+        }
+
+        dbus_server_setup_with_g_main (server, NULL);
+        dbus_server_set_new_connection_function (server,
+                                                 on_new_connection,
+                                                 data,
+                                                 NULL);
+        /* Allow only anonymous auth */
+        if (!dbus_server_set_auth_mechanisms (server, auth_mechanisms)) {
+                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                             _("Error setting auth mechanisms on local DBusServer\n"));
+                goto out;
+        }
+
+        command_line = g_strdup_printf ("ssh "
+                                        "-T "
+                                        "-C "
+                                        "-R 0:localhost:%d "
+                                        "-o \"ForwardX11 no\" "
+                                        "-o \"ForwardAgent no\" "
+                                        "-o \"Protocol 2\" "
+                                        "-o \"NoHostAuthenticationForLocalhost yes\" "
+                                        "%s",
+                                        local_port,
+                                        ssh_address);
+        //g_print ("command line: `%s'\n", command_line);
+        if (!g_shell_parse_argv (command_line,
+                                 &ssh_argc,
+                                 &ssh_argv,
+                                 &local_error)) {
+                g_set_error (error,
+                             GDU_ERROR,
+                             GDU_ERROR_FAILED,
+                             _("Unable to parse command-line `%s' (Malformed address?): %s"),
+                             command_line,
+                             local_error->message);
+                g_error_free (local_error);
+                goto out;
+        }
+
+
+        if (!g_spawn_async_with_pipes (NULL,
+                                       ssh_argv,
+                                       NULL,
+                                       G_SPAWN_SEARCH_PATH,
+                                       NULL,
+                                       NULL,
+                                       &ssh_pid,
+                                       &stdin_fd,
+                                       &stdout_fd,
+                                       &stderr_fd,
+                                       &local_error)) {
+                g_set_error (error,
+                             GDU_ERROR,
+                             GDU_ERROR_FAILED,
+                             _("Unable to spawn ssh program: %s"),
+                             local_error->message);
+                g_error_free (local_error);
+                goto out;
+        }
+
+        stdin_stream = g_unix_output_stream_new (stdin_fd, TRUE);
+        stdout_stream = g_unix_input_stream_new (stdout_fd, TRUE);
+        stderr_stream = g_unix_input_stream_new (stderr_fd, TRUE);
+        stdin_data_stream = g_data_output_stream_new (stdin_stream);
+        stdout_data_stream = g_data_input_stream_new (stdout_stream);
+        stderr_data_stream = g_data_input_stream_new (stderr_stream);
+        g_object_unref (stdin_stream);
+        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;
+        }
+        //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
+         */
+        s = g_strdup_printf ("/usr/lib/udisks/udisks-tcp-bridge -p %d\n", remote_port);
+        if (!g_data_output_stream_put_string (stdin_data_stream,
+                                              s,
+                                              NULL,
+                                              &local_error)) {
+                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                             _("Error executing `%s' on host `%s': %s"),
+                             s, ssh_address, local_error->message);
+                g_error_free (local_error);
+                g_free (s);
+                goto out;
+        }
+        g_free (s);
+
+        /* Check that the udisks program is waiting for secret
+         */
+        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 from udisks-tcp-bridge program on 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': "
+                               "Expected `udisks-tcp-bridge: Waiting for secret' but got `%s'"),
+                             ssh_address, s);
+                g_free (s);
+                goto out;
+        }
+        g_free (s);
+
+        /* Pass the secret
+         */
+        s = g_strdup_printf ("%s\n", data->secret);
+        if (!g_data_output_stream_put_string (stdin_data_stream,
+                                              s,
+                                              NULL,
+                                              &local_error)) {
+                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                             _("Error passing authorization secret to host `%s': %s"),
+                             ssh_address, local_error->message);
+                g_error_free (local_error);
+                memset (s, '\0', strlen (s));
+                g_free (s);
+                goto out;
+        }
+        memset (s, '\0', strlen (s));
+        g_free (s);
+
+        /* Check that the udisks program really is attempting to connect (for cases
+         * where the program doesn't exist on the host
+         */
+        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 from udisks-tcp-bridge program on 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': "
+                               "Expected `udisks-tcp-bridge: Attempting to connect to port %d' but got `%s'"),
+                             ssh_address, remote_port, s);
+                g_free (s);
+                goto out;
+        }
+        g_free (s);
+
+        /* Wait for connection and authorization */
+        data->loop = g_main_loop_new (NULL, FALSE);
+        g_main_loop_run (data->loop);
+
+        if (data->server_connection != NULL) {
+                if (data->authorized) {
+                        ret = dbus_connection_get_g_connection (dbus_connection_ref (data->server_connection));
+                } else {
+                        dbus_connection_close (data->server_connection);
+                        g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                                     _("The udisks-tcp-bridge program on host `%s' didn't prove it was "
+                                       "authorized: %s"),
+                                     ssh_address,
+                                     data->error_message != NULL ? data->error_message : "(no detail)");
+                }
+        } else {
+                g_set_error (error, GDU_ERROR, GDU_ERROR_FAILED,
+                             _("The udisks-tcp-bridge program on host `%s' didn't prove it was "
+                               "authorized"),
+                             ssh_address);
+        }
+
+ out:
+        if (data != NULL)
+                bridge_data_free (data);
+        if (server != NULL)
+                dbus_server_unref (server);
+        if (stdin_data_stream != NULL)
+                g_object_unref (stdin_data_stream);
+        if (stdout_data_stream != NULL)
+                g_object_unref (stdout_data_stream);
+        if (stderr_data_stream != NULL)
+                g_object_unref (stderr_data_stream);
+        g_strfreev (ssh_argv);
+        g_free (command_line);
+        g_free (dbus_address);
+        return ret;
+}
diff --git a/src/gdu/gdu-ssh-bridge.h b/src/gdu/gdu-ssh-bridge.h
new file mode 100644
index 0000000..11c336b
--- /dev/null
+++ b/src/gdu/gdu-ssh-bridge.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 David Zeuthen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#if defined (__GDU_INSIDE_GDU_H)
+#error "Can't include a private header in the public header file."
+#endif
+
+
+#ifndef __GDU_SSH_BRIDGE_H
+#define __GDU_SSH_BRIDGE_H
+
+#include <dbus/dbus-glib.h>
+#include "gdu-types.h"
+
+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 9a33e5a..2b1d1fe 100644
--- a/src/palimpsest/gdu-main.c
+++ b/src/palimpsest/gdu-main.c
@@ -179,7 +179,10 @@ main (int argc, char **argv)
                         return 1;
         }
 
-        shell = gdu_shell_new (dbus_address);
+        GMountOperation *connect_operation;
+        connect_operation = gtk_mount_operation_new (NULL);
+        shell = gdu_shell_new (dbus_address, connect_operation);
+        g_object_unref (connect_operation);
 
         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 e46ebbd..0539e58 100644
--- a/src/palimpsest/gdu-shell.c
+++ b/src/palimpsest/gdu-shell.c
@@ -42,7 +42,7 @@
 
 struct _GduShellPrivate
 {
-        gchar *dbus_address;
+        gchar *ssh_address;
 
         GtkWidget *app_window;
         GduPool *pool;
@@ -70,7 +70,7 @@ G_DEFINE_TYPE (GduShell, gdu_shell, G_TYPE_OBJECT);
 static void
 gdu_shell_finalize (GduShell *shell)
 {
-        g_free (shell->priv->dbus_address);
+        g_free (shell->priv->ssh_address);
         if (G_OBJECT_CLASS (parent_class)->finalize)
                 (* G_OBJECT_CLASS (parent_class)->finalize) (G_OBJECT (shell));
 }
@@ -87,7 +87,8 @@ gdu_shell_class_init (GduShellClass *klass)
         g_type_class_add_private (klass, sizeof (GduShellPrivate));
 }
 
-static void create_window (GduShell *shell);
+static void create_window (GduShell        *shell,
+                           GMountOperation *connect_operation);
 
 static void
 gdu_shell_init (GduShell *shell)
@@ -96,12 +97,13 @@ gdu_shell_init (GduShell *shell)
 }
 
 GduShell *
-gdu_shell_new (const gchar *dbus_address)
+gdu_shell_new (const gchar     *ssh_address,
+               GMountOperation *connect_operation)
 {
         GduShell *shell;
         shell = GDU_SHELL (g_object_new (GDU_TYPE_SHELL, NULL));
-        shell->priv->dbus_address = g_strdup (dbus_address);
-        create_window (shell);
+        shell->priv->ssh_address = g_strdup (ssh_address);
+        create_window (shell, connect_operation);
         return shell;
 }
 
@@ -1657,7 +1659,8 @@ gdu_shell_raise_error (GduShell       *shell,
 }
 
 static void
-create_window (GduShell *shell)
+create_window (GduShell *shell,
+               GMountOperation *connect_operation)
 {
         GtkWidget *vbox;
         GtkWidget *vbox1;
@@ -1671,7 +1674,7 @@ create_window (GduShell *shell)
         GduPoolTreeModel *model;
         GtkTreeViewColumn *column;
 
-        shell->priv->pool = gdu_pool_new_for_address (shell->priv->dbus_address);
+        shell->priv->pool = gdu_pool_new_for_address (shell->priv->ssh_address, connect_operation);
 
         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 f5b8e0b..f281227 100644
--- a/src/palimpsest/gdu-shell.h
+++ b/src/palimpsest/gdu-shell.h
@@ -54,7 +54,8 @@ struct _GduShellClass
 };
 
 GType           gdu_shell_get_type                 (void);
-GduShell       *gdu_shell_new                      (const char *dbus_address);
+GduShell       *gdu_shell_new                      (const char      *ssh_address,
+                                                    GMountOperation *connect_operation);
 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]