diff options
author | Yongha Hwang <mshrimp@sogang.ac.kr> | 2021-07-05 20:40:59 +0000 |
---|---|---|
committer | Alexander Schwinn <alexxcons@xfce.org> | 2021-07-05 20:40:59 +0000 |
commit | 888ee36645fb489568496392ad57b8ad6ffc08fe (patch) | |
tree | ac3e22ce5e20ea599a6651e64dd5ddb2da946684 /plugins | |
parent | 3504b0a74648ccd825959ae41143a65c9361a415 (diff) | |
download | thunar-888ee36645fb489568496392ad57b8ad6ffc08fe.tar.gz |
Add possibility to 'trust' launchers (Issue #156)
Only using the executable flag to 'trust' launchers is insecure, because the flag e.g. can be pre-set in archives.
'Trusting' a launcher now will generate a checksum of the launcher and store it via gvfs-metadata.
MR !121
Fixes #156
Related Merge requests:
https://gitlab.xfce.org/xfce/exo/-/merge_requests/44
https://gitlab.xfce.org/xfce/libxfce4util/-/merge_requests/16
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/thunar-apr/Makefile.am | 4 | ||||
-rw-r--r-- | plugins/thunar-apr/thunar-apr-desktop-page.c | 365 |
2 files changed, 335 insertions, 34 deletions
diff --git a/plugins/thunar-apr/Makefile.am b/plugins/thunar-apr/Makefile.am index e78e3863..f5277d21 100644 --- a/plugins/thunar-apr/Makefile.am +++ b/plugins/thunar-apr/Makefile.am @@ -27,6 +27,8 @@ thunar_apr_la_SOURCES = \ thunar_apr_la_CFLAGS = \ $(EXIF_CFLAGS) \ $(EXO_CFLAGS) \ + $(LIBXFCE4UTIL_CFLAGS) \ + $(LIBXFCE4UI_CFLAGS) \ $(GLIB_CFLAGS) \ $(GTK_CFLAGS) \ $(PLATFORM_CFLAGS) @@ -43,6 +45,8 @@ thunar_apr_la_LIBADD = \ $(top_builddir)/thunarx/libthunarx-$(THUNARX_VERSION_API).la \ $(EXIF_LIBS) \ $(EXO_LIBS) \ + $(LIBXFCE4UTIL_LIBS) \ + $(LIBXFCE4UI_LIBS) \ $(GLIB_LIBS) \ $(GTK_LIBS) diff --git a/plugins/thunar-apr/thunar-apr-desktop-page.c b/plugins/thunar-apr/thunar-apr-desktop-page.c index 8afa7470..9b820f4d 100644 --- a/plugins/thunar-apr/thunar-apr-desktop-page.c +++ b/plugins/thunar-apr/thunar-apr-desktop-page.c @@ -38,6 +38,8 @@ #include <exo/exo.h> +#include <libxfce4ui/libxfce4ui.h> +#include <libxfce4util/libxfce4util.h> #include <thunar-apr/thunar-apr-desktop-page.h> /* use g_access() on win32 */ @@ -49,21 +51,30 @@ -static void thunar_apr_desktop_page_finalize (GObject *object); -static void thunar_apr_desktop_page_file_changed (ThunarAprAbstractPage *abstract_page, - ThunarxFileInfo *file); -static void thunar_apr_desktop_page_save (ThunarAprDesktopPage *desktop_page, - GtkWidget *widget); -static void thunar_apr_desktop_page_save_widget (ThunarAprDesktopPage *desktop_page, - GtkWidget *widget, - GKeyFile *key_file); -static void thunar_apr_desktop_page_activated (GtkWidget *entry, - ThunarAprDesktopPage *desktop_page); -static gboolean thunar_apr_desktop_page_focus_out_event (GtkWidget *entry, - GdkEventFocus *event, - ThunarAprDesktopPage *desktop_page); -static void thunar_apr_desktop_page_toggled (GtkWidget *button, - ThunarAprDesktopPage *desktop_page); +static void thunar_apr_desktop_page_finalize (GObject *object); +static void thunar_apr_desktop_page_file_changed (ThunarAprAbstractPage *abstract_page, + ThunarxFileInfo *file); +static void thunar_apr_desktop_page_save (ThunarAprDesktopPage *desktop_page, + GtkWidget *widget); +static void thunar_apr_desktop_page_save_widget (ThunarAprDesktopPage *desktop_page, + GtkWidget *widget, + GKeyFile *key_file); +static void thunar_apr_desktop_page_activated (GtkWidget *entry, + ThunarAprDesktopPage *desktop_page); +static gboolean thunar_apr_desktop_page_focus_out_event (GtkWidget *entry, + GdkEventFocus *event, + ThunarAprDesktopPage *desktop_page); +static void thunar_apr_desktop_page_toggled (GtkWidget *button, + ThunarAprDesktopPage *desktop_page); +static void thunar_apr_desktop_page_program_toggled (GtkWidget *button, + ThunarAprDesktopPage *desktop_page); +static void thunar_apr_desktop_page_trusted_toggled (GtkWidget *button, + ThunarAprDesktopPage *desktop_page); +static gboolean is_executable (GFile *gfile, + GError **error); +static gboolean set_executable (GFile *gfile, + gboolean executable, + GError **error); @@ -83,6 +94,8 @@ struct _ThunarAprDesktopPage GtkWidget *comment_entry; GtkWidget *snotify_button; GtkWidget *terminal_button; + GtkWidget *program_button; + GtkWidget *trusted_button; /* the values of the entries remember when * the file was saved last time to avoid a @@ -107,6 +120,86 @@ THUNARX_DEFINE_TYPE (ThunarAprDesktopPage, +static gboolean +is_executable (GFile *gfile, + GError **error) +{ + GError *error_local = NULL; + GFileInfo *info; + gboolean executable; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (G_IS_FILE (gfile), FALSE); + + info = g_file_query_info (gfile, + G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, + G_FILE_QUERY_INFO_NONE, + NULL, + &error_local); + if (error_local != NULL) + { + g_propagate_error (error, error_local); + return FALSE; + } + + executable = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE); + g_object_unref (info); + + return executable; +} + + + +/* copied from exo-die-utils.c */ +static gboolean +set_executable (GFile *gfile, + gboolean executable, + GError **error) +{ + GError *error_local = NULL; + guint32 mode = 0111, mask = 0111; + guint32 old_mode, new_mode; + GFileInfo *info; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (G_IS_FILE (gfile), FALSE); + + + info = g_file_query_info (gfile, + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_QUERY_INFO_NONE, + NULL, + &error_local); + + if (error_local != NULL) + { + g_propagate_error (error, error_local); + return FALSE; + } + + old_mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE); + new_mode = executable ? ((old_mode & ~mask) | mode) : (old_mode & ~mask); + + if (old_mode != new_mode) { + g_file_set_attribute_uint32 (gfile, + G_FILE_ATTRIBUTE_UNIX_MODE, new_mode, + G_FILE_QUERY_INFO_NONE, + NULL, + &error_local); + } + g_object_unref (info); + + if (error_local != NULL) + { + g_propagate_error (error, error_local); + return FALSE; + } + + return TRUE; +} + + + static void thunar_apr_desktop_page_class_init (ThunarAprDesktopPageClass *klass) { @@ -134,6 +227,9 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) GtkWidget *grid; GtkWidget *label; GtkWidget *spacer; + guint row = 0; + GFile *gfile; + gboolean metadata_supported; gtk_container_set_border_width (GTK_CONTAINER (desktop_page), 12); @@ -153,7 +249,7 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) label = gtk_label_new (_("Description:")); gtk_label_set_xalign (GTK_LABEL (label), 1.0f); gtk_label_set_attributes (GTK_LABEL (label), attr_list); - gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1); + gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); gtk_widget_show (label); desktop_page->description_entry = gtk_entry_new (); @@ -162,7 +258,7 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) g_signal_connect (G_OBJECT (desktop_page->description_entry), "activate", G_CALLBACK (thunar_apr_desktop_page_activated), desktop_page); g_signal_connect (G_OBJECT (desktop_page->description_entry), "focus-out-event", G_CALLBACK (thunar_apr_desktop_page_focus_out_event), desktop_page); gtk_widget_set_hexpand (desktop_page->description_entry, TRUE); - gtk_grid_attach (GTK_GRID (grid), desktop_page->description_entry, 1, 0, 1, 1); + gtk_grid_attach (GTK_GRID (grid), desktop_page->description_entry, 1, row, 1, 1); gtk_widget_show (desktop_page->description_entry); g_object_bind_property (G_OBJECT (desktop_page->description_entry), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); @@ -174,10 +270,12 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) atk_relation_set_add (relations, relation); g_object_unref (G_OBJECT (relation)); + row++; + label = gtk_label_new (_("Command:")); gtk_label_set_xalign (GTK_LABEL (label), 1.0f); gtk_label_set_attributes (GTK_LABEL (label), attr_list); - gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1); + gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); gtk_widget_show (label); desktop_page->command_entry = gtk_entry_new (); @@ -185,7 +283,7 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) g_signal_connect (G_OBJECT (desktop_page->command_entry), "activate", G_CALLBACK (thunar_apr_desktop_page_activated), desktop_page); g_signal_connect (G_OBJECT (desktop_page->command_entry), "focus-out-event", G_CALLBACK (thunar_apr_desktop_page_focus_out_event), desktop_page); gtk_widget_set_hexpand (desktop_page->command_entry, TRUE); - gtk_grid_attach (GTK_GRID (grid), desktop_page->command_entry, 1, 1, 1, 1); + gtk_grid_attach (GTK_GRID (grid), desktop_page->command_entry, 1, row, 1, 1); gtk_widget_show (desktop_page->command_entry); g_object_bind_property (G_OBJECT (desktop_page->command_entry), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); @@ -197,10 +295,12 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) atk_relation_set_add (relations, relation); g_object_unref (G_OBJECT (relation)); + row++; + label = gtk_label_new (_("Working Directory:")); gtk_label_set_xalign (GTK_LABEL (label), 1.0f); gtk_label_set_attributes (GTK_LABEL (label), attr_list); - gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1); + gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); gtk_widget_show (label); desktop_page->path_entry = gtk_entry_new (); @@ -208,7 +308,7 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) g_signal_connect (G_OBJECT (desktop_page->path_entry), "activate", G_CALLBACK (thunar_apr_desktop_page_activated), desktop_page); g_signal_connect (G_OBJECT (desktop_page->path_entry), "focus-out-event", G_CALLBACK (thunar_apr_desktop_page_focus_out_event), desktop_page); gtk_widget_set_hexpand (desktop_page->path_entry, TRUE); - gtk_grid_attach (GTK_GRID (grid), desktop_page->path_entry, 1, 2, 1, 1); + gtk_grid_attach (GTK_GRID (grid), desktop_page->path_entry, 1, row, 1, 1); gtk_widget_show (desktop_page->path_entry); g_object_bind_property (G_OBJECT (desktop_page->path_entry), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); @@ -220,10 +320,12 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) atk_relation_set_add (relations, relation); g_object_unref (G_OBJECT (relation)); + row++; + label = gtk_label_new (_("URL:")); gtk_label_set_xalign (GTK_LABEL (label), 1.0f); gtk_label_set_attributes (GTK_LABEL (label), attr_list); - gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1); + gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); gtk_widget_show (label); desktop_page->url_entry = gtk_entry_new (); @@ -231,7 +333,7 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) g_signal_connect (G_OBJECT (desktop_page->url_entry), "activate", G_CALLBACK (thunar_apr_desktop_page_activated), desktop_page); g_signal_connect (G_OBJECT (desktop_page->url_entry), "focus-out-event", G_CALLBACK (thunar_apr_desktop_page_focus_out_event), desktop_page); gtk_widget_set_hexpand (desktop_page->url_entry, TRUE); - gtk_grid_attach (GTK_GRID (grid), desktop_page->url_entry, 1, 3, 1, 1); + gtk_grid_attach (GTK_GRID (grid), desktop_page->url_entry, 1, row, 1, 1); gtk_widget_show (desktop_page->url_entry); g_object_bind_property (G_OBJECT (desktop_page->url_entry), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); @@ -243,10 +345,12 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) atk_relation_set_add (relations, relation); g_object_unref (G_OBJECT (relation)); + row++; + label = gtk_label_new (_("Comment:")); gtk_label_set_xalign (GTK_LABEL (label), 1.0f); gtk_label_set_attributes (GTK_LABEL (label), attr_list); - gtk_grid_attach (GTK_GRID (grid), label, 0, 4, 1, 1); + gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); gtk_widget_show (label); desktop_page->comment_entry = gtk_entry_new (); @@ -256,7 +360,7 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) g_signal_connect (G_OBJECT (desktop_page->comment_entry), "activate", G_CALLBACK (thunar_apr_desktop_page_activated), desktop_page); g_signal_connect (G_OBJECT (desktop_page->comment_entry), "focus-out-event", G_CALLBACK (thunar_apr_desktop_page_focus_out_event), desktop_page); gtk_widget_set_hexpand (desktop_page->comment_entry, TRUE); - gtk_grid_attach (GTK_GRID (grid), desktop_page->comment_entry, 1, 4, 1, 1); + gtk_grid_attach (GTK_GRID (grid), desktop_page->comment_entry, 1, row, 1, 1); gtk_widget_show (desktop_page->comment_entry); g_object_bind_property (G_OBJECT (desktop_page->comment_entry), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); @@ -268,15 +372,23 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) atk_relation_set_add (relations, relation); g_object_unref (G_OBJECT (relation)); + row++; + + /* Nothing here on purpose */ + + row++; + /* add spacing between the entries and the options */ spacer = g_object_new (GTK_TYPE_BOX, "orientation", GTK_ORIENTATION_VERTICAL, "height-request", 12, NULL); - gtk_grid_attach (GTK_GRID (grid), spacer, 0, 6, 2, 1); + gtk_grid_attach (GTK_GRID (grid), spacer, 0, row, 2, 1); gtk_widget_show (spacer); + row++; + label = gtk_label_new (_("Options:")); gtk_label_set_xalign (GTK_LABEL (label), 1.0f); gtk_label_set_attributes (GTK_LABEL (label), attr_list); - gtk_grid_attach (GTK_GRID (grid), label, 0, 7, 1, 1); + gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); gtk_widget_show (label); desktop_page->snotify_button = gtk_check_button_new_with_mnemonic (_("Use _startup notification")); @@ -285,28 +397,81 @@ thunar_apr_desktop_page_init (ThunarAprDesktopPage *desktop_page) "startup notification.")); g_signal_connect (G_OBJECT (desktop_page->snotify_button), "toggled", G_CALLBACK (thunar_apr_desktop_page_toggled), desktop_page); gtk_widget_set_hexpand (desktop_page->snotify_button, TRUE); - gtk_grid_attach (GTK_GRID (grid), desktop_page->snotify_button, 1, 7, 1, 1); + gtk_grid_attach (GTK_GRID (grid), desktop_page->snotify_button, 1, row, 1, 1); gtk_widget_show (desktop_page->snotify_button); + g_object_bind_property (G_OBJECT (desktop_page->snotify_button), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); + + /* set Atk label relation for the buttons */ + relations = atk_object_ref_relation_set (gtk_widget_get_accessible (label)); + object = gtk_widget_get_accessible (desktop_page->snotify_button); + relation = atk_relation_new (&object, 1, ATK_RELATION_LABEL_FOR); + atk_relation_set_add (relations, relation); + g_object_unref (G_OBJECT (relation)); + + row++; + desktop_page->terminal_button = gtk_check_button_new_with_mnemonic (_("Run in _terminal")); gtk_widget_set_tooltip_text (desktop_page->terminal_button, _("Select this option to run the command in a terminal window.")); g_signal_connect (G_OBJECT (desktop_page->terminal_button), "toggled", G_CALLBACK (thunar_apr_desktop_page_toggled), desktop_page); gtk_widget_set_hexpand (desktop_page->terminal_button, TRUE); - gtk_grid_attach (GTK_GRID (grid), desktop_page->terminal_button, 1, 8, 1, 1); + gtk_grid_attach (GTK_GRID (grid), desktop_page->terminal_button, 1, row, 1, 1); gtk_widget_show (desktop_page->terminal_button); + /* don't bind visibility with label */ + /* set Atk label relation for the buttons */ relations = atk_object_ref_relation_set (gtk_widget_get_accessible (label)); - object = gtk_widget_get_accessible (desktop_page->snotify_button); - relation = atk_relation_new (&object, 1, ATK_RELATION_LABEL_FOR); - atk_relation_set_add (relations, relation); - g_object_unref (G_OBJECT (relation)); object = gtk_widget_get_accessible (desktop_page->terminal_button); relation = atk_relation_new (&object, 1, ATK_RELATION_LABEL_FOR); atk_relation_set_add (relations, relation); g_object_unref (G_OBJECT (relation)); - g_object_bind_property (G_OBJECT (desktop_page->snotify_button), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); + row++; + + label = gtk_label_new (_("Security:")); + gtk_label_set_xalign (GTK_LABEL (label), 1.0f); + gtk_label_set_attributes (GTK_LABEL (label), attr_list); + gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); + gtk_widget_show (label); + + /* same function as in thunar-permission-chooser.c */ + desktop_page->program_button = gtk_check_button_new_with_mnemonic (_("Allow this file to _run as a .desktop file")); + gtk_widget_set_tooltip_text (desktop_page->program_button, _("Select this to enable executable permission bit(+x). Thunar will not launch the .desktop file if not set.")); + g_signal_connect (G_OBJECT (desktop_page->program_button), "toggled", + G_CALLBACK (thunar_apr_desktop_page_program_toggled), desktop_page); + gtk_widget_set_hexpand (desktop_page->program_button, TRUE); + gtk_grid_attach (GTK_GRID (grid), desktop_page->program_button, 1, row, 1, 1); + gtk_widget_show (desktop_page->program_button); + + g_object_bind_property (G_OBJECT (desktop_page->program_button), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); + xfce_gtk_label_set_a11y_relation (GTK_LABEL (label), desktop_page->program_button); + + row++; + + gfile = g_file_new_for_uri ("file:///"); + metadata_supported = xfce_g_file_metadata_is_supported (gfile); + g_object_unref (gfile); + if (metadata_supported) + { + desktop_page->trusted_button = gtk_check_button_new_with_mnemonic (_("Set this file as trusted")); + gtk_widget_set_tooltip_text (desktop_page->trusted_button, _("Select this option to trust this .desktop file. This will generate a checksum of the file and store it via gvfs. The additional check will protect from malicious launchers which e.g. pretend to be a picture, having the executable flag pre-set")); + g_signal_connect (G_OBJECT (desktop_page->trusted_button), "toggled", + G_CALLBACK (thunar_apr_desktop_page_trusted_toggled), desktop_page); + gtk_widget_set_hexpand (desktop_page->trusted_button, TRUE); + gtk_grid_attach (GTK_GRID (grid), desktop_page->trusted_button, 1, row, 1, 1); + gtk_widget_show (desktop_page->trusted_button); + + g_object_bind_property (G_OBJECT (desktop_page->trusted_button), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE); + xfce_gtk_label_set_a11y_relation (GTK_LABEL (label), desktop_page->trusted_button); + + row++; + } + else + { + g_info ("metadata not supported"); + desktop_page->trusted_button = NULL; + } /* release shared bold Pango attributes */ pango_attr_list_unref (attr_list); @@ -337,8 +502,11 @@ thunar_apr_desktop_page_file_changed (ThunarAprAbstractPage *abstract_page, { ThunarAprDesktopPage *desktop_page = THUNAR_APR_DESKTOP_PAGE (abstract_page); GKeyFile *key_file; + GFile *gfile; gboolean writable; gboolean enabled; + gboolean executable; + gboolean trusted; GError *error = NULL; gchar *filename; gchar *value; @@ -492,6 +660,35 @@ thunar_apr_desktop_page_file_changed (ThunarAprAbstractPage *abstract_page, gtk_widget_hide (desktop_page->terminal_button); } + /* update flags */ + gfile = thunarx_file_info_get_location (abstract_page->file); + + executable = is_executable (gfile, &error); + if (error != NULL) + { + g_warning ("Failed to initialize program_button : %s", error->message); + g_clear_error (&error); + } + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (desktop_page->program_button), executable); + + if (desktop_page->trusted_button != NULL) + { + trusted = xfce_g_file_is_trusted (gfile, NULL, &error); + if (error != NULL) + { + g_warning ("Failed to initialize trusted_button : %s", error->message); + g_clear_error (&error); + } + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (desktop_page->trusted_button), trusted); + } + + g_object_unref (gfile); + + /* show security */ + gtk_widget_show (desktop_page->program_button); + if (desktop_page->trusted_button != NULL) + gtk_widget_show (desktop_page->trusted_button); + /* check if the file is writable... */ writable = (g_access (filename, W_OK) == 0); @@ -520,6 +717,9 @@ thunar_apr_desktop_page_file_changed (ThunarAprAbstractPage *abstract_page, gtk_widget_hide (desktop_page->comment_entry); gtk_widget_hide (desktop_page->snotify_button); gtk_widget_hide (desktop_page->terminal_button); + gtk_widget_hide (desktop_page->program_button); + if (desktop_page->trusted_button != NULL) + gtk_widget_hide (desktop_page->trusted_button); } /* cleanup */ @@ -542,6 +742,8 @@ thunar_apr_desktop_page_save (ThunarAprDesktopPage *desktop_page, gchar *uri; gsize data_length; FILE *fp; + GFile *gfile; + gboolean trusted; /* verify that we still have a valid file */ if (THUNAR_APR_ABSTRACT_PAGE (desktop_page)->file == NULL) @@ -579,6 +781,10 @@ thunar_apr_desktop_page_save (ThunarAprDesktopPage *desktop_page, data = g_key_file_to_data (key_file, &data_length, &error); if (G_LIKELY (data_length > 0)) { + trusted = FALSE; + if (desktop_page->trusted_button != NULL) + trusted = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (desktop_page->trusted_button)); + /* try to save the key file content to disk */ fp = fopen (filename, "w"); if (G_LIKELY (fp != NULL)) @@ -591,6 +797,14 @@ thunar_apr_desktop_page_save (ThunarAprDesktopPage *desktop_page, { error = g_error_new_literal (G_FILE_ERROR, g_file_error_from_errno (errno), g_strerror (errno)); } + + /* Update safety flag checksum */ + if (trusted && error == NULL) + { + gfile = thunarx_file_info_get_location (THUNAR_APR_ABSTRACT_PAGE (desktop_page)->file); + xfce_g_file_set_trusted (gfile, trusted, NULL, &error); + g_object_unref (gfile); + } } /* cleanup */ @@ -798,3 +1012,86 @@ thunar_apr_desktop_page_toggled (GtkWidget *button, thunar_apr_desktop_page_save (desktop_page, button); } + + +/** + * Allowed state: + * + * +-----+-----+ + * |EXE |SAFE | + * +=====+=====+ + * |TRUE |TRUE | Allowed to launch + * +-----+-----+ + * |TRUE |FALSE| Ask before launch + * +-----+-----+ + * |FALSE|FALSE| Not recognized as .desktop + * +-----+-----+ + **/ +static void +thunar_apr_desktop_page_program_toggled (GtkWidget *button, + ThunarAprDesktopPage *desktop_page) +{ + GError *error = NULL; + GFile *gfile; + gboolean executable; + gboolean trusted; + + g_return_if_fail (button == desktop_page->program_button); + g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button)); + g_return_if_fail (THUNAR_APR_IS_DESKTOP_PAGE (desktop_page)); + g_return_if_fail (THUNARX_IS_FILE_INFO (THUNAR_APR_ABSTRACT_PAGE (desktop_page)->file)); + + gfile = thunarx_file_info_get_location (THUNAR_APR_ABSTRACT_PAGE (desktop_page)->file); + + executable = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (desktop_page->program_button)); + set_executable (gfile, executable, &error); + + g_object_unref (gfile); + + if (error != NULL) + { + g_warning ("Error while setting execution flag : %s", error->message); + g_free (error); + return; + } + + trusted = (desktop_page->trusted_button != NULL) ? gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (desktop_page->trusted_button)) : FALSE; + /* if the executable flag is unset, that will as well unset the trusted flag */ + if (!executable && trusted) + if (desktop_page->trusted_button != NULL) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (desktop_page->trusted_button), FALSE); +} + +static void +thunar_apr_desktop_page_trusted_toggled (GtkWidget *button, + ThunarAprDesktopPage *desktop_page) +{ + GError *error = NULL; + GFile *gfile; + gboolean executable; + gboolean trusted; + + g_return_if_fail (button == desktop_page->trusted_button); + g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button)); + g_return_if_fail (THUNAR_APR_IS_DESKTOP_PAGE (desktop_page)); + g_return_if_fail (THUNARX_IS_FILE_INFO (THUNAR_APR_ABSTRACT_PAGE (desktop_page)->file)); + + gfile = thunarx_file_info_get_location (THUNAR_APR_ABSTRACT_PAGE (desktop_page)->file); + + trusted = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (desktop_page->trusted_button)); + xfce_g_file_set_trusted (gfile, trusted, NULL, &error); + + g_object_unref (gfile); + + if (error != NULL) + { + g_warning ("Error while setting safety flag : %s", error->message); + g_free (error); + return; + } + + executable = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (desktop_page->program_button)); + /* setting the trusted flag automatically sets the execute flag */ + if (!executable && trusted) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (desktop_page->program_button), TRUE); +} |