132 lines
3.9 KiB
Plaintext
132 lines
3.9 KiB
Plaintext
|
$OpenBSD: patch-gio_gunixconnection_c,v 1.1 2011/04/28 13:07:53 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 Thu Apr 14 00:55:29 2011
|
||
|
+++ gio/gunixconnection.c Wed Apr 27 18:54:47 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,25 @@ 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;
|
||
|
- scm = g_unix_credentials_message_new_with_credentials (credentials);
|
||
|
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 +373,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 +417,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 +512,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 +542,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:
|
||
|
|