summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYongha Hwang <mshrimp@sogang.ac.kr>2021-06-23 21:06:20 +0000
committerAlexander Schwinn <alexxcons@xfce.org>2021-06-23 21:06:20 +0000
commitc881265b1e421bbf1cbf3f6afe5649f96cd8decc (patch)
tree44fdc0dad35a7fc84c1c7721e91a7807ce157e6d
parent4abb3b553af89351366655a8a7ecf41ea8cdb564 (diff)
downloadlibxfce4util-c881265b1e421bbf1cbf3f6afe5649f96cd8decc.tar.gz
xfce-gio-extensions
Related : thunar#156 (comment 18095) xfce_g_file_metadata_is_supported : Check if metadata is supported xfce_g_file_create_checksum : Generate SHA-256 of the file xfce_g_file_set_trusted : Set trusted attribute/checksum in metadata xfce_g_file_is_trusted : Check trusted attribute/checksum MR !16
-rw-r--r--docs/reference/libxfce4util-docs.xml1
-rw-r--r--docs/reference/libxfce4util-sections.txt9
-rw-r--r--libxfce4util/Makefile.am2
-rw-r--r--libxfce4util/libxfce4util.h1
-rw-r--r--libxfce4util/libxfce4util.symbols10
-rw-r--r--libxfce4util/xfce-gio-extensions.c327
-rw-r--r--libxfce4util/xfce-gio-extensions.h42
7 files changed, 392 insertions, 0 deletions
diff --git a/docs/reference/libxfce4util-docs.xml b/docs/reference/libxfce4util-docs.xml
index ea5888d..5b7f742 100644
--- a/docs/reference/libxfce4util-docs.xml
+++ b/docs/reference/libxfce4util-docs.xml
@@ -49,6 +49,7 @@
<xi:include href="xml/xfce-fileutils.xml"/>
<xi:include href="xml/xfce-miscutils.xml"/>
<xi:include href="xml/xfce-utf8.xml"/>
+ <xi:include href="xml/xfce-gio-extensions.xml"/>
</chapter>
<chapter id="libxfce4util-datatypes">
diff --git a/docs/reference/libxfce4util-sections.txt b/docs/reference/libxfce4util-sections.txt
index 4563cd9..3832504 100644
--- a/docs/reference/libxfce4util-sections.txt
+++ b/docs/reference/libxfce4util-sections.txt
@@ -112,6 +112,15 @@ xfce_utf8_strndup
xfce_mkdirhier
</SECTION>
+<SECTION>
+<TITLE>GIO Extensions</TITLE>
+<FILE>xfce-gio-extensions</FILE>
+xfce_g_file_metadata_is_supported
+xfce_g_file_create_checksum
+xfce_g_file_set_trusted
+xfce_g_file_is_trusted
+</SECTION>
+
<SECTION>
<TITLE>Software Licenses</TITLE>
diff --git a/libxfce4util/Makefile.am b/libxfce4util/Makefile.am
index 996706e..a309a62 100644
--- a/libxfce4util/Makefile.am
+++ b/libxfce4util/Makefile.am
@@ -24,6 +24,7 @@ libxfce4util_headers = \
xfce-debug.h \
xfce-fileutils.h \
xfce-generics.h \
+ xfce-gio-extensions.h \
xfce-i18n.h \
xfce-kiosk.h \
xfce-license.h \
@@ -50,6 +51,7 @@ libxfce4util_la_SOURCES = \
libxfce4util-private.c \
libxfce4util-private.h \
xfce-fileutils.c \
+ xfce-gio-extensions.c \
xfce-i18n.c \
xfce-kiosk.c \
xfce-license.c \
diff --git a/libxfce4util/libxfce4util.h b/libxfce4util/libxfce4util.h
index 5cbd0ee..ea110cc 100644
--- a/libxfce4util/libxfce4util.h
+++ b/libxfce4util/libxfce4util.h
@@ -37,6 +37,7 @@
#include <libxfce4util/xfce-rc.h>
#include <libxfce4util/xfce-resource.h>
#include <libxfce4util/xfce-utf8.h>
+#include <libxfce4util/xfce-gio-extensions.h>
#undef LIBXFCE4UTIL_INSIDE_LIBXFCE4UTIL_H
diff --git a/libxfce4util/libxfce4util.symbols b/libxfce4util/libxfce4util.symbols
index db4ae00..17da2c1 100644
--- a/libxfce4util/libxfce4util.symbols
+++ b/libxfce4util/libxfce4util.symbols
@@ -52,6 +52,16 @@ xfce_mkdirhier
#endif
#endif
+/* xfce-gio-extensions functions */
+#if IN_HEADER(__XFCE_GIO_EXTENSIONS_H__)
+#if IN_SOURCE(__XFCE_GIO_EXTENSIONS_C__)
+xfce_g_file_metadata_is_supported
+xfce_g_file_create_checksum
+xfce_g_file_set_trusted
+xfce_g_file_is_trusted
+#endif
+#endif
+
/* xfce-i18n functions */
#if IN_HEADER(__XFCE_I18N_H__)
#if IN_SOURCE(__XFCE_I18N_C__)
diff --git a/libxfce4util/xfce-gio-extensions.c b/libxfce4util/xfce-gio-extensions.c
new file mode 100644
index 0000000..2f994bf
--- /dev/null
+++ b/libxfce4util/xfce-gio-extensions.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2021 Yongha Hwang <mshrimp@sogang.ac.kr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/**
+ * SECTION:xfce-gio-extensions
+ * @title: GIO Extensions
+ * @short_description: various extensions to GIO
+ * @include: libxfce4util/libxfce4util.h
+ *
+ * Common used functions for I/O that are not provided by the Glib library
+ *
+ * Since: 4.17
+ **/
+
+
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4util/libxfce4util-alias.h>
+
+
+
+#define XFCE_ATTRIBUTE_EXECUTABLE_CHECKSUM "metadata::xfce-exe-checksum" /* string */
+
+
+
+/**
+ * xfce_g_file_metadata_is_supported:
+ * @file: a #GFile.
+ *
+ * Checks if GVFS-metadata is available for
+ * the @file provided.
+ *
+ * Returns: %TRUE is GVFS-metadata is supported, %FALSE otherwise.
+ *
+ * Since: 4.17
+ **/
+gboolean
+xfce_g_file_metadata_is_supported (GFile *file)
+{
+ GFileAttributeInfoList *info_list;
+ gboolean is_supported;
+
+ g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+ info_list = g_file_query_writable_namespaces (file, NULL, NULL);
+ if (info_list == NULL)
+ return FALSE;
+
+ is_supported = (g_file_attribute_info_list_lookup (info_list, "metadata") != NULL);
+ g_file_attribute_info_list_unref (info_list);
+
+ return is_supported;
+}
+
+
+
+/**
+ * xfce_g_file_create_checksum:
+ * @file: a #GFile.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: (nullable): a #GError
+ *
+ * Generates an SHA-256 hash of the @file.
+ * Utilizes g_compute_checksum_for_data() which
+ * is present since Glib 2.16.
+ *
+ * Returns: (transfer full) (nullable): Checksum of the @file.
+ * If file read fails, returns %NULL. Free with g_free().
+ *
+ * Since: 4.17
+ **/
+gchar *
+xfce_g_file_create_checksum (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *error_local = NULL;
+ GFileInfo *file_info;
+ GFileInputStream *stream;
+ guchar *contents_buffer;
+ gchar *checksum;
+ gsize file_size, file_size_read;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+
+ /* query size */
+ file_info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_SIZE,
+ G_FILE_QUERY_INFO_NONE,
+ cancellable,
+ &error_local);
+ if (error_local != NULL)
+ {
+ g_propagate_error (error, error_local);
+ return NULL;
+ }
+
+ file_size = g_file_info_get_size (file_info);
+ g_object_unref (file_info);
+
+ /* special case : SHA-256 hash of NULL */
+ /* e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 */
+ if (file_size == 0)
+ return g_compute_checksum_for_data (G_CHECKSUM_SHA256, NULL, 0);
+
+ /* allocate buffer */
+ contents_buffer = g_malloc (file_size);
+ if (contents_buffer == NULL)
+ {
+ if (error != NULL)
+ *error = g_error_new (G_FILE_ERROR,
+ G_FILE_ERROR_NOMEM,
+ "Failed to allocate memory to read file '%s'",
+ g_file_peek_path (file));
+ return NULL;
+ }
+
+ /* read the actual file */
+ stream = g_file_read (file, cancellable, &error_local);
+ if (error_local != NULL)
+ {
+ g_free (contents_buffer);
+ g_propagate_error (error, error_local);
+ return NULL;
+ }
+
+ g_input_stream_read_all (G_INPUT_STREAM (stream),
+ contents_buffer,
+ file_size,
+ &file_size_read,
+ cancellable,
+ &error_local);
+ g_object_unref (stream);
+
+ if (error_local != NULL)
+ {
+ g_free (contents_buffer);
+ g_propagate_error (error, error_local);
+ return NULL;
+ }
+
+ checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
+ contents_buffer,
+ file_size_read);
+
+ g_free (contents_buffer);
+
+ return checksum;
+}
+
+
+
+/**
+ * xfce_g_file_set_trusted:
+ * @file: a #GFile.
+ * @is_trusted: #TRUE if trusted, #FALSE if not
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: (nullable): a #GError
+ *
+ * Sets the "safety flag" on if @is_trusted.
+ *
+ * Safety flag is a new concept introduced in
+ * XFCE 4.17. It is basically an additional
+ * execution flag stored in GVFS-metadata.
+ * Unlike the execution flag (+x), it is safe
+ * to assume that this flag did not come from
+ * foreign location (for example, by downloading
+ * an tar archive) and is set by user.
+ *
+ * The checksum of the file is stored, and
+ * would be considered "on" only if checksum
+ * matches with the file on execution.
+ *
+ * Returns: %TRUE on success, %FALSE on error.
+ *
+ * Since: 4.17
+ **/
+gboolean
+xfce_g_file_set_trusted (GFile *file,
+ gboolean is_trusted,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *error_local = NULL;
+ gchar *checksum_string;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+ if (!xfce_g_file_metadata_is_supported (file))
+ {
+ if (error != NULL)
+ *error = g_error_new (G_FILE_ERROR,
+ G_FILE_ERROR_NOSYS,
+ "GVFS-metadata is not supported for file '%s'",
+ g_file_peek_path (file));
+ return FALSE;
+ }
+
+ if (is_trusted)
+ {
+ checksum_string = xfce_g_file_create_checksum (file, cancellable, &error_local);
+ if (error_local != NULL)
+ {
+ g_propagate_error (error, error_local);
+ return FALSE;
+ }
+ }
+ else
+ checksum_string = NULL;
+
+ g_file_set_attribute (file,
+ XFCE_ATTRIBUTE_EXECUTABLE_CHECKSUM,
+ is_trusted ? G_FILE_ATTRIBUTE_TYPE_STRING : G_FILE_ATTRIBUTE_TYPE_INVALID,
+ checksum_string,
+ G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE | G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED,
+ cancellable,
+ &error_local);
+ g_free (checksum_string);
+
+ if (error_local != NULL)
+ {
+ g_propagate_error (error, error_local);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+
+/**
+ * xfce_g_file_is_trusted:
+ * @file: a #GFile.
+ * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
+ * @error: (nullable): a #GError
+ *
+ * Compares the checksum stored in safety flag
+ * with the actual file. If it matches, it
+ * is considered safe.
+ *
+ * Read the documentation of
+ * xfce_g_file_set_trusted() for details.
+ *
+ * Returns: %TRUE if safety flag is verified
+ * or not supported. %FALSE otherwise.
+ *
+ * Since: 4.17
+ **/
+gboolean
+xfce_g_file_is_trusted (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *error_local = NULL;
+ GFileInfo *file_info;
+ gboolean is_trusted;
+ const gchar *attribute_string;
+ gchar *checksum_string;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+ if (!xfce_g_file_metadata_is_supported (file))
+ {
+ if (error != NULL)
+ *error = g_error_new (G_FILE_ERROR,
+ G_FILE_ERROR_NOSYS,
+ "GVFS-metadata is not supported for file '%s'",
+ g_file_peek_path (file));
+ return TRUE;
+ }
+
+ file_info = g_file_query_info (file,
+ XFCE_ATTRIBUTE_EXECUTABLE_CHECKSUM,
+ G_FILE_QUERY_INFO_NONE,
+ cancellable,
+ &error_local);
+ if (error_local != NULL)
+ {
+ g_propagate_error (error, error_local);
+ return FALSE;
+ }
+
+ attribute_string = g_file_info_get_attribute_string (file_info,
+ XFCE_ATTRIBUTE_EXECUTABLE_CHECKSUM);
+ if (attribute_string != NULL)
+ {
+ checksum_string = xfce_g_file_create_checksum (file, cancellable, &error_local);
+ if (error_local != NULL)
+ {
+ g_object_unref (file_info);
+ g_propagate_error (error, error_local);
+ return FALSE;
+ }
+ is_trusted = (g_strcmp0 (attribute_string, checksum_string) == 0);
+ g_info ("== Safety flag check ==");
+ g_info ("Attribute checksum: %s", attribute_string);
+ g_info ("File checksum : %s", checksum_string);
+ g_free (checksum_string);
+ }
+ else
+ is_trusted = FALSE;
+
+ g_object_unref (file_info);
+
+ return is_trusted;
+}
+
+#define __XFCE_GIO_EXTENSIONS_C__
+#include <libxfce4util/libxfce4util-aliasdef.c>
diff --git a/libxfce4util/xfce-gio-extensions.h b/libxfce4util/xfce-gio-extensions.h
new file mode 100644
index 0000000..aa58e06
--- /dev/null
+++ b/libxfce4util/xfce-gio-extensions.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2021 Yongha Hwang <mshrimp@sogang.ac.kr>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#if !defined(LIBXFCE4UTIL_INSIDE_LIBXFCE4UTIL_H) && !defined(LIBXFCE4UTIL_COMPILATION)
+#error "Only <libxfce4util/libxfce4util.h> can be included directly, this file may disappear or change contents"
+#endif
+
+#ifndef __XFCE_GIO_EXTENSIONS_H__
+#define __XFCE_GIO_EXTENSIONS_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+gboolean xfce_g_file_metadata_is_supported (GFile *file);
+gchar *xfce_g_file_create_checksum (GFile *file,
+ GCancellable *cancellable,
+ GError **error);
+gboolean xfce_g_file_set_trusted (GFile *file,
+ gboolean is_trusted,
+ GCancellable *cancellable,
+ GError **error);
+gboolean xfce_g_file_is_trusted (GFile *file,
+ GCancellable *cancellable,
+ GError **error);
+
+#endif /*__XFCE_GIO_EXTENSIONS_H__*/