File 0001-boo1155768-getsockopt-style-APIs.patch of Package glib2.11726
The original patch is available at:
https://gitlab.gnome.org/GNOME/glib/merge_requests/1176/diffs?commit_id=ee502dbbe89a5976c32eb8863c9a9d274ddb60e1
Backported for glib 2.54.3
diff -ur a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
--- a/gio/gcredentialsprivate.h 2017-07-14 08:03:38.000000000 +0900
+++ b/gio/gcredentialsprivate.h 2019-12-27 23:24:01.830812183 +0900
@@ -22,6 +22,18 @@
#include "gio/gcredentials.h"
#include "gio/gnetworking.h"
+/*
+ * G_CREDENTIALS_PREFER_MESSAGE_PASSING:
+ *
+ * Defined to 1 if the data structure transferred by the message-passing
+ * API is strictly more informative than the one transferred by the
+ * `getsockopt()`-style API, and hence should be preferred, even for
+ * protocols like D-Bus that are defined in terms of the credentials of
+ * the (process that opened the) socket, as opposed to the credentials
+ * of an individual message.
+ */
+#undef G_CREDENTIALS_PREFER_MESSAGE_PASSING
+
#ifdef __linux__
#define G_CREDENTIALS_SUPPORTED 1
#define G_CREDENTIALS_USE_LINUX_UCRED 1
@@ -30,6 +42,12 @@
#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
+/* GLib doesn't implement it yet, but FreeBSD's getsockopt()-style API
+ * is getpeereid(), which is not as informative as struct cmsgcred -
+ * it does not tell us the PID. As a result, libdbus prefers to use
+ * SCM_CREDS, and if we implement getpeereid() in future, we should
+ * do the same. */
+#define G_CREDENTIALS_PREFER_MESSAGE_PASSING 1
#elif defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) /* Debian GNU/kFreeBSD */ || \
diff -ur a/gio/gdbusauth.c b/gio/gdbusauth.c
--- a/gio/gdbusauth.c 2018-01-09 05:00:42.000000000 +0900
+++ b/gio/gdbusauth.c 2019-12-27 23:15:11.938749620 +0900
@@ -31,6 +31,7 @@
#include "gdbusutils.h"
#include "gioenumtypes.h"
#include "gcredentials.h"
+#include "gcredentialsprivate.h"
#include "gdbusprivate.h"
#include "giostream.h"
#include "gdatainputstream.h"
@@ -997,9 +998,32 @@
g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
- /* first read the NUL-byte (TODO: read credentials if using a unix domain socket) */
+ /* read the NUL-byte, possibly with credentials attached */
#ifdef G_OS_UNIX
- if (G_IS_UNIX_CONNECTION (auth->priv->stream))
+
+#ifndef G_CREDENTIALS_PREFER_MESSAGE_PASSING
+ if (G_IS_SOCKET_CONNECTION (auth->priv->stream))
+ {
+ GSocket *sock = g_socket_connection_get_socket (G_SOCKET_CONNECTION (auth->priv->stream));
+
+ local_error = NULL;
+ credentials = g_socket_get_credentials (sock, &local_error);
+
+ if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
+ {
+ g_propagate_error (error, local_error);
+ goto out;
+ }
+ else
+ {
+ /* Clear the error indicator, so we can retry with
+ * g_unix_connection_receive_credentials() if necessary */
+ g_clear_error (&local_error);
+ }
+ }
+#endif
+
+ if (credentials == NULL && G_IS_UNIX_CONNECTION (auth->priv->stream))
{
local_error = NULL;
credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream),