openbsd-ports/devel/glib2/patches/patch-gio_gunixconnection_c
2011-05-23 16:36:13 +00:00

134 lines
3.9 KiB
Plaintext

$OpenBSD: patch-gio_gunixconnection_c,v 1.2 2011/05/23 16:36:13 ajacoutot Exp $
XXX
Workaround the fact that we cannot pass SCM_CREDS over unix sockets:
implement the "intended" SCM_CREDS stack as if we had support for that
in the kernel (by-pass it almost completely).
send/recv a single null byte without creds, but on recv, just do a
getsockopt(SO_PEERCRED) and return that as if it coming from the cmsg.
This works as long as creds are not retreived from an fd which has
already been handed over to a different process via SCM_RIGHTS. It will
probably not be enough in the future but we'll see then.
--- gio/gunixconnection.c.orig Sat May 21 05:29:24 2011
+++ gio/gunixconnection.c Mon May 23 18:20:08 2011
@@ -42,7 +42,7 @@
#include <gio/gsocket.h>
#include <unistd.h>
-#ifdef __linux__
+#if defined(__linux__) || defined(__OpenBSD__)
/* for getsockopt() and setsockopt() */
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
@@ -328,8 +328,10 @@ g_unix_connection_send_credentials (GUnixConnection
GCancellable *cancellable,
GError **error)
{
+#ifndef __OpenBSD__
GCredentials *credentials;
GSocketControlMessage *scm;
+#endif
GSocket *socket;
gboolean ret;
GOutputVector vector;
@@ -340,18 +342,28 @@ g_unix_connection_send_credentials (GUnixConnection
ret = FALSE;
+#ifndef __OpenBSD__
credentials = g_credentials_new ();
+ scm = g_unix_credentials_message_new_with_credentials (credentials);
+#endif
vector.buffer = &nul_byte;
vector.size = 1;
+#ifndef __OpenBSD__
scm = g_unix_credentials_message_new_with_credentials (credentials);
+#endif
g_object_get (connection, "socket", &socket, NULL);
if (g_socket_send_message (socket,
NULL, /* address */
&vector,
1,
+#ifndef __OpenBSD__
&scm,
1,
+#else
+ NULL,
+ 0,
+#endif
G_SOCKET_MSG_NONE,
cancellable,
error) != 1)
@@ -364,8 +376,10 @@ g_unix_connection_send_credentials (GUnixConnection
out:
g_object_unref (socket);
+#ifndef __OpenBSD__
g_object_unref (scm);
g_object_unref (credentials);
+#endif
return ret;
}
@@ -406,6 +420,10 @@ g_unix_connection_receive_credentials (GUnixConnection
#ifdef __linux__
gboolean turn_off_so_passcreds;
#endif
+#ifdef __OpenBSD__
+ struct sockpeercred cred;
+ socklen_t len;
+#endif
g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
@@ -497,16 +515,25 @@ g_unix_connection_receive_credentials (GUnixConnection
goto out;
}
+#ifndef __OpenBSD__
if (nscm != 1)
+#else
+ if (nscm != 0)
+#endif
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
+#ifndef __OpenBSD__
_("Expecting 1 control message, got %d"),
+#else
+ _("Expecting 0 control message, got %d"),
+#endif
nscm);
goto out;
}
+#ifndef __OpenBSD__
if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0]))
{
g_set_error_literal (error,
@@ -518,6 +545,21 @@ g_unix_connection_receive_credentials (GUnixConnection
ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0]));
g_object_ref (ret);
+#else
+ len = sizeof(cred);
+ if (getsockopt(g_socket_get_fd(socket),
+ SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1) {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ _("Error : getsockopt(SO_PEERCRED): %s"),
+ strerror (errno));
+ goto out;
+ }
+
+ ret = g_credentials_new();
+ g_credentials_set_native(ret, G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED, &cred);
+#endif
out: