From 7632a3e13874a2c5e8988428ca913620a25df983 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 24 Feb 2009 11:21:10 +0000 Subject: [PATCH] Check for trusted desktop file launchers. 2009-02-24 Alexander Larsson * libnautilus-private/nautilus-directory-async.c: Check for trusted desktop file launchers. * libnautilus-private/nautilus-file-private.h: * libnautilus-private/nautilus-file.c: * libnautilus-private/nautilus-file.h: Add nautilus_file_is_trusted_link. Allow unsetting of custom display name. * libnautilus-private/nautilus-mime-actions.c: Display dialog when trying to launch a non-trusted desktop file. svn path=/trunk/; revision=15003 --- ChangeLog | 14 ++ .../nautilus-directory-async.c | 60 ++++++- libnautilus-private/nautilus-file-private.h | 1 + libnautilus-private/nautilus-file.c | 23 ++- libnautilus-private/nautilus-file.h | 1 + libnautilus-private/nautilus-mime-actions.c | 149 +++++++++++++++++- 6 files changed, 230 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ffcf8ea5..ac780a0e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2009-02-24 Alexander Larsson + + * libnautilus-private/nautilus-directory-async.c: + Check for trusted desktop file launchers. + + * libnautilus-private/nautilus-file-private.h: + * libnautilus-private/nautilus-file.c: + * libnautilus-private/nautilus-file.h: + Add nautilus_file_is_trusted_link. + Allow unsetting of custom display name. + + * libnautilus-private/nautilus-mime-actions.c: + Display dialog when trying to launch a non-trusted desktop file. + 2009-02-23 Paolo Borelli * src/file-manager/fm-list-view.c (sort_criterion_changes_due_to_user): diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c index 283e2f49d..7b1bacb83 100644 --- a/libnautilus-private/nautilus-directory-async.c +++ b/libnautilus-private/nautilus-directory-async.c @@ -3571,6 +3571,50 @@ file_info_start (NautilusDirectory *directory, g_object_unref (location); } +static gboolean +is_link_trusted (NautilusFile *file, + gboolean is_launcher) +{ + gboolean res; + + if (!is_launcher) { + return TRUE; + } + + if (nautilus_file_can_execute (file)) { + return TRUE; + } + + res = FALSE; + + if (nautilus_file_is_local (file)) { + const char * const * data_dirs; + char *uri, *path; + int i; + + data_dirs = g_get_system_data_dirs (); + + path = NULL; + uri = nautilus_file_get_uri (file); + if (uri) { + path = g_filename_from_uri (uri, NULL, NULL); + g_free (uri); + } + + for (i = 0; path != NULL && data_dirs[i] != NULL; i++) { + if (g_str_has_prefix (path, data_dirs[i])) { + res = TRUE; + break; + } + + } + g_free (path); + } + + + return res; +} + static void link_info_done (NautilusDirectory *directory, NautilusFile *file, @@ -3580,12 +3624,21 @@ link_info_done (NautilusDirectory *directory, gboolean is_launcher, gboolean is_foreign) { + gboolean is_trusted; + file->details->link_info_is_up_to_date = TRUE; - nautilus_file_set_display_name (file, name, name, TRUE); + is_trusted = is_link_trusted (file, is_launcher); + + if (is_trusted) { + nautilus_file_set_display_name (file, name, name, TRUE); + } else { + nautilus_file_set_display_name (file, NULL, NULL, TRUE); + } file->details->got_link_info = TRUE; g_free (file->details->custom_icon); + file->details->custom_icon = NULL; if (uri) { if (file->details->activation_location) { g_object_unref (file->details->activation_location); @@ -3594,9 +3647,12 @@ link_info_done (NautilusDirectory *directory, file->details->got_custom_activation_location = TRUE; file->details->activation_location = g_file_new_for_uri (uri); } - file->details->custom_icon = g_strdup (icon); + if (is_trusted) { + file->details->custom_icon = g_strdup (icon); + } file->details->is_launcher = is_launcher; file->details->is_foreign_link = is_foreign; + file->details->is_trusted_link = is_trusted; nautilus_directory_async_state_changed (directory); } diff --git a/libnautilus-private/nautilus-file-private.h b/libnautilus-private/nautilus-file-private.h index 3d4e95ab4..f3cb5b2aa 100644 --- a/libnautilus-private/nautilus-file-private.h +++ b/libnautilus-private/nautilus-file-private.h @@ -198,6 +198,7 @@ struct NautilusFileDetails eel_boolean_bit has_open_window : 1; eel_boolean_bit is_launcher : 1; + eel_boolean_bit is_trusted_link : 1; eel_boolean_bit is_foreign_link : 1; eel_boolean_bit is_symlink : 1; eel_boolean_bit is_mountpoint : 1; diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c index 1fce69d98..2952aed27 100644 --- a/libnautilus-private/nautilus-file.c +++ b/libnautilus-private/nautilus-file.c @@ -195,14 +195,6 @@ nautilus_file_set_display_name (NautilusFile *file, { gboolean changed; - if (display_name == NULL || *display_name == 0) { - return FALSE; - } - - if (!custom && file->details->got_custom_display_name) { - return FALSE; - } - if (custom && display_name == NULL) { /* We're re-setting a custom display name, invalidate it if we already set it so that the old one is re-read */ @@ -213,6 +205,14 @@ nautilus_file_set_display_name (NautilusFile *file, } return FALSE; } + + if (display_name == NULL || *display_name == 0) { + return FALSE; + } + + if (!custom && file->details->got_custom_display_name) { + return FALSE; + } if (edit_name == NULL) { edit_name = display_name; @@ -295,6 +295,7 @@ nautilus_file_clear_info (NautilusFile *file) file->details->is_launcher = FALSE; file->details->is_foreign_link = FALSE; + file->details->is_trusted_link = FALSE; file->details->is_symlink = FALSE; file->details->is_hidden = FALSE; file->details->is_backup = FALSE; @@ -3174,6 +3175,12 @@ nautilus_file_is_foreign_link (NautilusFile *file) return file->details->is_foreign_link; } +gboolean +nautilus_file_is_trusted_link (NautilusFile *file) +{ + return file->details->is_trusted_link; +} + gboolean nautilus_file_has_activation_uri (NautilusFile *file) { diff --git a/libnautilus-private/nautilus-file.h b/libnautilus-private/nautilus-file.h index a8d924772..85e3683ca 100644 --- a/libnautilus-private/nautilus-file.h +++ b/libnautilus-private/nautilus-file.h @@ -399,6 +399,7 @@ GList *nautilus_file_list_filter_hidden_and_backup (GList */ gboolean nautilus_file_is_launcher (NautilusFile *file); gboolean nautilus_file_is_foreign_link (NautilusFile *file); +gboolean nautilus_file_is_trusted_link (NautilusFile *file); gboolean nautilus_file_has_activation_uri (NautilusFile *file); char * nautilus_file_get_activation_uri (NautilusFile *file); GFile * nautilus_file_get_activation_location (NautilusFile *file); diff --git a/libnautilus-private/nautilus-mime-actions.c b/libnautilus-private/nautilus-mime-actions.c index c865f9b40..406ae2280 100644 --- a/libnautilus-private/nautilus-mime-actions.c +++ b/libnautilus-private/nautilus-mime-actions.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -83,6 +84,7 @@ typedef struct { #define RESPONSE_RUN 1000 #define RESPONSE_DISPLAY 1001 #define RESPONSE_RUN_IN_TERMINAL 1002 +#define RESPONSE_MARK_TRUSTED 1003 #define SILENT_WINDOW_OPEN_LIMIT 5 @@ -1044,6 +1046,7 @@ activate_parameters_install_free (ActivateParametersInstall *parameters_install) if (parameters_install->parent_window) { g_object_remove_weak_pointer (G_OBJECT (parameters_install->parent_window), (gpointer *)¶meters_install->parent_window); } + nautilus_file_unref (parameters_install->file); nautilus_file_list_free (parameters_install->files); g_free (parameters_install->activation_directory); g_free (parameters_install); @@ -1266,6 +1269,142 @@ out: g_free (error_message); } +typedef struct { + GtkWindow *parent_window; + NautilusFile *file; +} ActivateParametersDesktop; + +static void +activate_parameters_desktop_free (ActivateParametersDesktop *parameters_desktop) +{ + if (parameters_desktop->parent_window) { + g_object_remove_weak_pointer (G_OBJECT (parameters_desktop->parent_window), (gpointer *)¶meters_desktop->parent_window); + } + nautilus_file_unref (parameters_desktop->file); + g_free (parameters_desktop); +} + +static void +mark_trusted_callback (NautilusFile *file, + GFile *result_location, + GError *error, + gpointer callback_data) +{ + ActivateParametersDesktop *parameters; + + parameters = callback_data; + if (error) { + eel_show_error_dialog (_("Unable to mark launcher trusted (executable)"), + error->message, + parameters->parent_window); + } + + activate_parameters_desktop_free (parameters); +} + +static void +untrusted_launcher_response_callback (GtkDialog *dialog, + int response_id, + ActivateParametersDesktop *parameters) +{ + GdkScreen *screen; + char *uri; + gboolean free_params; + + free_params = TRUE; + switch (response_id) { + case RESPONSE_RUN: + screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window)); + uri = nautilus_file_get_uri (parameters->file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view activate_callback launch_desktop_file window=%p: %s", + parameters->parent_window, uri); + nautilus_launch_desktop_file (screen, uri, NULL, + parameters->parent_window); + g_free (uri); + break; + case RESPONSE_MARK_TRUSTED: + nautilus_file_set_permissions (parameters->file, + nautilus_file_get_permissions (parameters->file) | S_IXGRP | S_IXUSR | S_IXOTH, + mark_trusted_callback, + parameters); + free_params = FALSE; + break; + default: + /* Just destroy dialog */ + break; + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); + if (free_params) { + activate_parameters_desktop_free (parameters); + } +} + +static void +activate_desktop_file (ActivateParameters *parameters, + NautilusFile *file) +{ + ActivateParametersDesktop *parameters_desktop; + char *primary, *secondary, *display_name; + GtkWidget *dialog; + GdkScreen *screen; + char *uri; + + screen = gtk_widget_get_screen (GTK_WIDGET (parameters->parent_window)); + + if (!nautilus_file_is_trusted_link (file)) { + /* copy the parts of parameters we are interested in as the orignal will be freed */ + parameters_desktop = g_new0 (ActivateParametersDesktop, 1); + if (parameters->parent_window) { + parameters_desktop->parent_window = parameters->parent_window; + g_object_add_weak_pointer (G_OBJECT (parameters_desktop->parent_window), (gpointer *)¶meters_desktop->parent_window); + } + parameters_desktop->file = nautilus_file_ref (file); + + primary = _("Untrusted application launcher"); + display_name = nautilus_file_get_display_name (file); + secondary = + g_strdup_printf (_("The application launcher \"%s\" has not been marked as trusted. " + "If you do not know the source of this file, launching it may be unsafe." + ), + display_name); + + dialog = eel_alert_dialog_new (parameters->parent_window, + 0, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_NONE, + primary, + secondary); + gtk_dialog_add_button (GTK_DIALOG (dialog), + _("_Launch anyway"), RESPONSE_RUN); + if (nautilus_file_can_set_permissions (file)) { + gtk_dialog_add_button (GTK_DIALOG (dialog), + _("Mark as _Trusted"), RESPONSE_MARK_TRUSTED); + } + gtk_dialog_add_button (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); + + g_signal_connect (dialog, "response", + G_CALLBACK (untrusted_launcher_response_callback), + parameters_desktop); + gtk_widget_show (dialog); + + g_free (display_name); + g_free (secondary); + return; + } + + uri = nautilus_file_get_uri (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view activate_callback launch_desktop_file window=%p: %s", + parameters->parent_window, uri); + nautilus_launch_desktop_file (screen, uri, NULL, + parameters->parent_window); + g_free (uri); +} + static void activate_files (ActivateParameters *parameters) { @@ -1340,14 +1479,8 @@ activate_files (ActivateParameters *parameters) launch_desktop_files = g_list_reverse (launch_desktop_files); for (l = launch_desktop_files; l != NULL; l = l->next) { file = NAUTILUS_FILE (l->data); - - uri = nautilus_file_get_uri (file); - nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, - "directory view activate_callback launch_desktop_file window=%p: %s", - parameters->parent_window, uri); - nautilus_launch_desktop_file (screen, uri, NULL, - parameters->parent_window); - g_free (uri); + + activate_desktop_file (parameters, file); } old_working_dir = NULL; -- GitLab