gvfs r1308 - in trunk: . common daemon
- From: alexl svn gnome org
- To: svn-commits-list gnome org
- Subject: gvfs r1308 - in trunk: . common daemon
- Date: Wed, 20 Feb 2008 12:38:37 +0000 (GMT)
Author: alexl
Date: Wed Feb 20 12:38:37 2008
New Revision: 1308
URL: http://svn.gnome.org/viewvc/gvfs?rev=1308&view=rev
Log:
2008-02-20 Alexander Larsson <alexl redhat com>
* common/gmountsource.[ch]:
Add ask_question support
* daemon/gvfsbackendsftp.c:
Handle host identity changed messages (#517460)
Patch from Carlos Garcia Campos
Modified:
trunk/ChangeLog
trunk/common/gmountsource.c
trunk/common/gmountsource.h
trunk/daemon/gvfsbackendsftp.c
Modified: trunk/common/gmountsource.c
==============================================================================
--- trunk/common/gmountsource.c (original)
+++ trunk/common/gmountsource.c Wed Feb 20 12:38:37 2008
@@ -131,9 +131,9 @@
GPasswordSave password_save;
};
-typedef struct AskPasswordSyncData AskPasswordSyncData;
+typedef struct AskSyncData AskSyncData;
-struct AskPasswordSyncData {
+struct AskSyncData {
/* For sync calls */
GMutex *mutex;
@@ -312,13 +312,13 @@
static void
-ask_password_reply_sync (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
+ask_reply_sync (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- AskPasswordSyncData *data;
+ AskSyncData *data;
- data = (AskPasswordSyncData *) user_data;
+ data = (AskSyncData *) user_data;
data->result = g_object_ref (res);
@@ -343,7 +343,7 @@
char *password, *username, *domain;
GPasswordSave password_save;
gboolean handled, aborted;
- AskPasswordSyncData data = {NULL};
+ AskSyncData data = {NULL};
if (password_out)
*password_out = NULL;
@@ -363,7 +363,7 @@
default_user,
default_domain,
flags,
- ask_password_reply_sync,
+ ask_reply_sync,
&data);
g_cond_wait(data.cond, data.mutex);
@@ -473,6 +473,224 @@
return TRUE;
}
+typedef struct AskQuestionData AskQuestionData;
+
+struct AskQuestionData {
+
+ /* results: */
+ gboolean aborted;
+ guint32 choice;
+};
+
+/* the callback from dbus -> main thread */
+static void
+ask_question_reply (DBusMessage *reply,
+ GError *error,
+ gpointer _data)
+{
+ GSimpleAsyncResult *result;
+ AskQuestionData *data;
+ dbus_bool_t handled, aborted;
+ guint32 choice;
+ DBusMessageIter iter;
+
+ result = G_SIMPLE_ASYNC_RESULT (_data);
+ handled = TRUE;
+
+ data = g_new0 (AskQuestionData, 1);
+ g_simple_async_result_set_op_res_gpointer (result, data, g_free);
+
+ if (reply == NULL)
+ {
+ data->aborted = TRUE;
+ }
+ else
+ {
+ dbus_message_iter_init (reply, &iter);
+ if (!_g_dbus_message_iter_get_args (&iter, NULL,
+ DBUS_TYPE_BOOLEAN, &handled,
+ DBUS_TYPE_BOOLEAN, &aborted,
+ DBUS_TYPE_UINT32, &choice,
+ 0))
+ data->aborted = TRUE;
+ else
+ {
+ data->aborted = aborted;
+ data->choice = choice;
+ }
+ }
+
+ if (handled == FALSE)
+ {
+ g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_FAILED, NULL);
+ }
+
+ g_simple_async_result_complete (result);
+}
+
+gboolean
+g_mount_source_ask_question (GMountSource *source,
+ const char *message,
+ const char **choices,
+ gint n_choices,
+ gboolean *aborted_out,
+ gint *choice_out)
+{
+ gint choice;
+ gboolean handled, aborted;
+ AskSyncData data = {NULL};
+
+ data.mutex = g_mutex_new ();
+ data.cond = g_cond_new ();
+
+ g_mutex_lock (data.mutex);
+
+ g_mount_source_ask_question_async (source,
+ message,
+ choices,
+ n_choices,
+ ask_reply_sync,
+ &data);
+
+ g_cond_wait(data.cond, data.mutex);
+ g_mutex_unlock (data.mutex);
+
+ g_cond_free (data.cond);
+ g_mutex_free (data.mutex);
+
+ handled = g_mount_source_ask_question_finish (source,
+ data.result,
+ &aborted,
+ &choice);
+
+ g_object_unref (data.result);
+
+ if (aborted_out)
+ *aborted_out = aborted;
+
+ if (choice_out)
+ *choice_out = choice;
+
+ return handled;
+}
+
+void
+g_mount_source_ask_question_async (GMountSource *source,
+ const char *message_string,
+ const char **choices,
+ gint n_choices,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ DBusMessage *message;
+
+ /* If no dbus id specified, reply that we weren't handled */
+ if (source->dbus_id[0] == 0)
+ {
+ g_simple_async_report_error_in_idle (G_OBJECT (source),
+ callback,
+ user_data,
+ G_IO_ERROR, G_IO_ERROR_FAILED, NULL);
+ return;
+ }
+
+ if (message_string == NULL)
+ message_string = "";
+
+ message = dbus_message_new_method_call (source->dbus_id,
+ source->obj_path,
+ G_VFS_DBUS_MOUNT_OPERATION_INTERFACE,
+ G_VFS_DBUS_MOUNT_OPERATION_OP_ASK_QUESTION);
+
+ _g_dbus_message_append_args (message,
+ DBUS_TYPE_STRING, &message_string,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ choices, n_choices,
+ 0);
+
+ result = g_simple_async_result_new (G_OBJECT (source), callback, user_data,
+ g_mount_source_ask_question_async);
+ /* 30 minute timeout */
+ _g_dbus_connection_call_async (NULL, message, 1000 * 60 * 30,
+ ask_question_reply, result);
+ dbus_message_unref (message);
+
+}
+
+gboolean
+g_mount_source_ask_question_finish (GMountSource *source,
+ GAsyncResult *result,
+ gboolean *aborted,
+ gint *choice_out)
+{
+ AskQuestionData *data;
+ GSimpleAsyncResult *simple;
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ if (g_simple_async_result_propagate_error (simple, NULL))
+ return FALSE;
+
+ data = (AskQuestionData *) g_simple_async_result_get_op_res_gpointer (simple);
+
+ if (aborted)
+ *aborted = data->aborted;
+
+ if (choice_out)
+ *choice_out = data->choice;
+
+ return TRUE;
+}
+
+static void
+op_ask_question_reply (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GMountOperationResult result;
+ GMountOperation *op;
+ GMountSource *source;
+ gboolean handled, aborted;
+ gint choice;
+
+ source = G_MOUNT_SOURCE (source_object);
+ op = G_MOUNT_OPERATION (user_data);
+
+ handled = g_mount_source_ask_question_finish (source,
+ res,
+ &aborted,
+ &choice);
+
+ if (!handled)
+ result = G_MOUNT_OPERATION_UNHANDLED;
+ else if (aborted)
+ result = G_MOUNT_OPERATION_ABORTED;
+ else
+ {
+ result = G_MOUNT_OPERATION_HANDLED;
+ g_mount_operation_set_choice (op, choice);
+ }
+
+ g_mount_operation_reply (op, result);
+ g_object_unref (op);
+}
+
+static gboolean
+op_ask_question (GMountOperation *op,
+ const char *message,
+ const char **choices,
+ gint n_choices,
+ GMountSource *mount_source)
+{
+ g_mount_source_ask_question_async (mount_source,
+ message,
+ choices,
+ n_choices,
+ op_ask_question_reply,
+ g_object_ref (op));
+ return TRUE;
+}
GMountOperation *
g_mount_source_get_operation (GMountSource *mount_source)
@@ -486,6 +704,7 @@
g_signal_connect (op, "ask_password", (GCallback)op_ask_password, mount_source);
+ g_signal_connect (op, "ask_question", (GCallback)op_ask_question, mount_source);
return op;
}
Modified: trunk/common/gmountsource.h
==============================================================================
--- trunk/common/gmountsource.h (original)
+++ trunk/common/gmountsource.h Wed Feb 20 12:38:37 2008
@@ -83,6 +83,25 @@
char **domain_out,
GPasswordSave *password_save_out);
+gboolean g_mount_source_ask_question (GMountSource *mount_source,
+ const char *message,
+ const char **choices,
+ gint n_choices,
+ gboolean *aborted,
+ gint *choice_out);
+
+void g_mount_source_ask_question_async (GMountSource *mount_source,
+ const char *message,
+ const char **choices,
+ gint n_choices,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean g_mount_source_ask_question_finish (GMountSource *source,
+ GAsyncResult *result,
+ gboolean *aborted,
+ gint *choice_out);
+
const char * g_mount_source_get_dbus_id (GMountSource *mount_source);
const char * g_mount_source_get_obj_path (GMountSource *mount_source);
Modified: trunk/daemon/gvfsbackendsftp.c
==============================================================================
--- trunk/daemon/gvfsbackendsftp.c (original)
+++ trunk/daemon/gvfsbackendsftp.c Wed Feb 20 12:38:37 2008
@@ -601,6 +601,64 @@
}
static gboolean
+get_hostname_and_fingerprint_from_line (const gchar *buffer,
+ gchar **hostname_out,
+ gchar **fingerprint_out)
+{
+ gchar *pos;
+ gchar *startpos;
+ gchar *endpos;
+ gchar *hostname = NULL;
+ gchar *fingerprint = NULL;
+
+ if (g_str_has_prefix (buffer, "The authenticity of host '"))
+ {
+ /* OpenSSH */
+ pos = strchr (&buffer[26], '\'');
+ if (pos == NULL)
+ return FALSE;
+
+ hostname = g_strndup (&buffer[26], pos - (&buffer[26]));
+
+ startpos = strstr (pos, " key fingerprint is ");
+ if (startpos == NULL)
+ {
+ g_free (hostname);
+ return FALSE;
+ }
+
+ startpos = startpos + 20;
+ endpos = strchr (startpos, '.');
+ if (endpos == NULL)
+ {
+ g_free (hostname);
+ return FALSE;
+ }
+
+ fingerprint = g_strndup (startpos, endpos - startpos);
+ }
+ else if (strstr (buffer, "Key fingerprint:") != NULL)
+ {
+ /* SSH.com*/
+ startpos = strstr (buffer, "Key fingerprint:");
+ if (startpos == NULL)
+ {
+ g_free (hostname);
+ return FALSE;
+ }
+
+ startpos = startpos + 18;
+ endpos = strchr (startpos, '\r');
+ fingerprint = g_strndup (startpos, endpos - startpos);
+ }
+
+ *hostname_out = hostname;
+ *fingerprint_out = fingerprint;
+
+ return TRUE;
+}
+
+static gboolean
handle_login (GVfsBackend *backend,
GMountSource *mount_source,
int tty_fd, int stdout_fd, int stderr_fd,
@@ -753,8 +811,61 @@
else if (g_str_has_prefix (buffer, "The authenticity of host '") ||
strstr (buffer, "Key fingerprint:") != NULL)
{
- /* TODO: Handle these messages */
- }
+ const gchar *choices[] = {_("Log In Anyway"), _("Cancel Login")};
+ const gchar *v_choices = (const gchar *)choices;
+ const gchar *choice_string;
+ gchar *hostname = NULL;
+ gchar *fingerprint = NULL;
+ gint choice;
+ gchar *message;
+
+ get_hostname_and_fingerprint_from_line (buffer, &hostname, &fingerprint);
+
+ message = g_strdup_printf (_("The identity of the remote computer (%s) is unknown.\n"
+ "This happens when you log in to a computer the first time.\n\n"
+ "The identity sent by the remote computer is %s. "
+ "If you want to be absolutely sure it is safe to continue, "
+ "contact the systema dministrator."),
+ hostname ? hostname : op_backend->host, fingerprint);
+
+ g_free (hostname);
+ g_free (fingerprint);
+
+ if (!g_mount_source_ask_question (mount_source,
+ message,
+ &v_choices,
+ 2,
+ &aborted,
+ &choice) ||
+ aborted)
+ {
+ g_set_error (error,
+ G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ "%s", _("Login dialog cancelled"));
+ g_free (message);
+ ret_val = FALSE;
+ break;
+ }
+ g_free (message);
+
+ choice_string = (choice == 0) ? "yes" : "no";
+ if (!g_output_stream_write_all (reply_stream,
+ choice_string,
+ strlen (choice_string),
+ &bytes_written,
+ NULL, NULL) ||
+ !g_output_stream_write_all (reply_stream,
+ "\n", 1,
+ &bytes_written,
+ NULL, NULL))
+ {
+ g_set_error (error,
+ G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ "%s", _("Can't send host identity confirmation"));
+ ret_val = FALSE;
+ break;
+ }
+ }
}
if (ret_val)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]