mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 07:26:15 +01:00
gio: add gcredential support for macOS
[smcv: Apply my review feedback from <https://bugzilla.gnome.org/show_bug.cgi?id=668866>] Co-authored-by: Simon McVittie <smcv@collabora.com> Resolves: https://gitlab.gnome.org/GNOME/glib/issues/507
This commit is contained in:
parent
05cb229082
commit
ec2f60a008
@ -55,6 +55,10 @@
|
|||||||
* unix(7) man page for details. This corresponds to
|
* unix(7) man page for details. This corresponds to
|
||||||
* %G_CREDENTIALS_TYPE_LINUX_UCRED.
|
* %G_CREDENTIALS_TYPE_LINUX_UCRED.
|
||||||
*
|
*
|
||||||
|
* On Apple operating systems (including iOS, tvOS, and macOS),
|
||||||
|
* the native credential type is a `struct xucred`.
|
||||||
|
* This corresponds to %G_CREDENTIALS_TYPE_APPLE_XUCRED.
|
||||||
|
*
|
||||||
* On FreeBSD, Debian GNU/kFreeBSD, and GNU/Hurd, the native
|
* On FreeBSD, Debian GNU/kFreeBSD, and GNU/Hurd, the native
|
||||||
* credential type is a `struct cmsgcred`. This corresponds
|
* credential type is a `struct cmsgcred`. This corresponds
|
||||||
* to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED.
|
* to %G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED.
|
||||||
@ -85,6 +89,8 @@ struct _GCredentials
|
|||||||
|
|
||||||
#if G_CREDENTIALS_USE_LINUX_UCRED
|
#if G_CREDENTIALS_USE_LINUX_UCRED
|
||||||
struct ucred native;
|
struct ucred native;
|
||||||
|
#elif G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
struct xucred native;
|
||||||
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
||||||
struct cmsgcred native;
|
struct cmsgcred native;
|
||||||
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
|
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
|
||||||
@ -148,6 +154,22 @@ g_credentials_init (GCredentials *credentials)
|
|||||||
credentials->native.pid = getpid ();
|
credentials->native.pid = getpid ();
|
||||||
credentials->native.uid = geteuid ();
|
credentials->native.uid = geteuid ();
|
||||||
credentials->native.gid = getegid ();
|
credentials->native.gid = getegid ();
|
||||||
|
#elif G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
credentials->native.cr_version = XUCRED_VERSION;
|
||||||
|
credentials->native.cr_uid = geteuid ();
|
||||||
|
credentials->native.cr_ngroups = 1;
|
||||||
|
credentials->native.cr_groups[0] = getegid ();
|
||||||
|
|
||||||
|
/* FIXME: In principle this could use getgroups() to fill in the rest
|
||||||
|
* of cr_groups, but then we'd have to handle the case where a process
|
||||||
|
* can have more than NGROUPS groups, if that's even possible. A macOS
|
||||||
|
* user would have to develop and test this.
|
||||||
|
*
|
||||||
|
* For now we fill it with -1 (meaning "no data"). */
|
||||||
|
for (i = 1; i < NGROUPS; i++)
|
||||||
|
credentials->native.cr_groups[i] = -1;
|
||||||
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
||||||
memset (&credentials->native, 0, sizeof (struct cmsgcred));
|
memset (&credentials->native, 0, sizeof (struct cmsgcred));
|
||||||
credentials->native.cmcred_pid = getpid ();
|
credentials->native.cmcred_pid = getpid ();
|
||||||
@ -202,6 +224,9 @@ gchar *
|
|||||||
g_credentials_to_string (GCredentials *credentials)
|
g_credentials_to_string (GCredentials *credentials)
|
||||||
{
|
{
|
||||||
GString *ret;
|
GString *ret;
|
||||||
|
#if G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
__typeof__(credentials->native.cr_ngroups) i;
|
||||||
|
#endif
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
|
g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
|
||||||
|
|
||||||
@ -216,6 +241,15 @@ g_credentials_to_string (GCredentials *credentials)
|
|||||||
g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
|
g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
|
||||||
if (ret->str[ret->len - 1] == ',')
|
if (ret->str[ret->len - 1] == ',')
|
||||||
ret->str[ret->len - 1] = '\0';
|
ret->str[ret->len - 1] = '\0';
|
||||||
|
#elif G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
g_string_append (ret, "apple-xucred:");
|
||||||
|
g_string_append_printf (ret, "version=%u,", credentials->native.cr_version);
|
||||||
|
if (credentials->native.cr_uid != -1)
|
||||||
|
g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cr_uid);
|
||||||
|
for (i = 0; i < credentials->native.cr_ngroups; i++)
|
||||||
|
g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cr_groups[i]);
|
||||||
|
if (ret->str[ret->len - 1] == ',')
|
||||||
|
ret->str[ret->len - 1] = '\0';
|
||||||
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
||||||
g_string_append (ret, "freebsd-cmsgcred:");
|
g_string_append (ret, "freebsd-cmsgcred:");
|
||||||
if (credentials->native.cmcred_pid != -1)
|
if (credentials->native.cmcred_pid != -1)
|
||||||
@ -326,6 +360,10 @@ g_credentials_is_same_user (GCredentials *credentials,
|
|||||||
if (linux_ucred_check_valid (&credentials->native, NULL)
|
if (linux_ucred_check_valid (&credentials->native, NULL)
|
||||||
&& credentials->native.uid == other_credentials->native.uid)
|
&& credentials->native.uid == other_credentials->native.uid)
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
#elif G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
if (credentials->native.cr_version == other_credentials->native.cr_version &&
|
||||||
|
credentials->native.cr_uid == other_credentials->native.cr_uid)
|
||||||
|
ret = TRUE;
|
||||||
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
||||||
if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
|
if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
@ -487,6 +525,21 @@ g_credentials_get_unix_user (GCredentials *credentials,
|
|||||||
ret = credentials->native.uid;
|
ret = credentials->native.uid;
|
||||||
else
|
else
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
#elif G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
if (credentials->native.cr_version == XUCRED_VERSION)
|
||||||
|
{
|
||||||
|
ret = credentials->native.cr_uid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
/* No point in translating the part in parentheses... */
|
||||||
|
"%s (struct xucred cr_version %u != %u)",
|
||||||
|
_("There is no GCredentials support for your platform"),
|
||||||
|
credentials->native.cr_version,
|
||||||
|
XUCRED_VERSION);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
||||||
ret = credentials->native.cmcred_euid;
|
ret = credentials->native.cmcred_euid;
|
||||||
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
|
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
|
||||||
@ -516,7 +569,8 @@ g_credentials_get_unix_user (GCredentials *credentials,
|
|||||||
*
|
*
|
||||||
* This operation can fail if #GCredentials is not supported on the
|
* This operation can fail if #GCredentials is not supported on the
|
||||||
* OS or if the native credentials type does not contain information
|
* OS or if the native credentials type does not contain information
|
||||||
* about the UNIX process ID.
|
* about the UNIX process ID (for example this is the case for
|
||||||
|
* %G_CREDENTIALS_TYPE_APPLE_XUCRED).
|
||||||
*
|
*
|
||||||
* Returns: The UNIX process ID, or -1 if @error is set.
|
* Returns: The UNIX process ID, or -1 if @error is set.
|
||||||
*
|
*
|
||||||
@ -545,6 +599,7 @@ g_credentials_get_unix_pid (GCredentials *credentials,
|
|||||||
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
|
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
|
||||||
ret = ucred_getpid (credentials->native);
|
ret = ucred_getpid (credentials->native);
|
||||||
#else
|
#else
|
||||||
|
/* this case includes G_CREDENTIALS_USE_APPLE_XUCRED */
|
||||||
ret = -1;
|
ret = -1;
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
@ -587,6 +642,9 @@ g_credentials_set_unix_user (GCredentials *credentials,
|
|||||||
#if G_CREDENTIALS_USE_LINUX_UCRED
|
#if G_CREDENTIALS_USE_LINUX_UCRED
|
||||||
credentials->native.uid = uid;
|
credentials->native.uid = uid;
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
#elif G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
credentials->native.cr_uid = uid;
|
||||||
|
ret = TRUE;
|
||||||
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
||||||
credentials->native.cmcred_euid = uid;
|
credentials->native.cmcred_euid = uid;
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#undef G_CREDENTIALS_USE_NETBSD_UNPCBID
|
#undef G_CREDENTIALS_USE_NETBSD_UNPCBID
|
||||||
#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
|
#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
|
||||||
#undef G_CREDENTIALS_USE_SOLARIS_UCRED
|
#undef G_CREDENTIALS_USE_SOLARIS_UCRED
|
||||||
|
#undef G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* G_CREDENTIALS_NATIVE_TYPE:
|
* G_CREDENTIALS_NATIVE_TYPE:
|
||||||
@ -156,6 +157,17 @@
|
|||||||
#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
|
#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
|
||||||
#define G_CREDENTIALS_HAS_PID 1
|
#define G_CREDENTIALS_HAS_PID 1
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include <sys/ucred.h>
|
||||||
|
#define G_CREDENTIALS_SUPPORTED 1
|
||||||
|
#define G_CREDENTIALS_USE_APPLE_XUCRED 1
|
||||||
|
#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_APPLE_XUCRED
|
||||||
|
#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct xucred))
|
||||||
|
#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
|
||||||
|
#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
|
||||||
|
#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
|
||||||
|
#define G_CREDENTIALS_HAS_PID 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __G_CREDENTIALS_PRIVATE_H__ */
|
#endif /* __G_CREDENTIALS_PRIVATE_H__ */
|
||||||
|
@ -1428,6 +1428,7 @@ typedef enum
|
|||||||
* @G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED: The native credentials type is a `struct sockpeercred`. Added in 2.30.
|
* @G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED: The native credentials type is a `struct sockpeercred`. Added in 2.30.
|
||||||
* @G_CREDENTIALS_TYPE_SOLARIS_UCRED: The native credentials type is a `ucred_t`. Added in 2.40.
|
* @G_CREDENTIALS_TYPE_SOLARIS_UCRED: The native credentials type is a `ucred_t`. Added in 2.40.
|
||||||
* @G_CREDENTIALS_TYPE_NETBSD_UNPCBID: The native credentials type is a `struct unpcbid`. Added in 2.42.
|
* @G_CREDENTIALS_TYPE_NETBSD_UNPCBID: The native credentials type is a `struct unpcbid`. Added in 2.42.
|
||||||
|
* @G_CREDENTIALS_TYPE_APPLE_XUCRED: The native credentials type is a `struct xucred`. Added in 2.66.
|
||||||
*
|
*
|
||||||
* Enumeration describing different kinds of native credential types.
|
* Enumeration describing different kinds of native credential types.
|
||||||
*
|
*
|
||||||
@ -1440,7 +1441,8 @@ typedef enum
|
|||||||
G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED,
|
G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED,
|
||||||
G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED,
|
G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED,
|
||||||
G_CREDENTIALS_TYPE_SOLARIS_UCRED,
|
G_CREDENTIALS_TYPE_SOLARIS_UCRED,
|
||||||
G_CREDENTIALS_TYPE_NETBSD_UNPCBID
|
G_CREDENTIALS_TYPE_NETBSD_UNPCBID,
|
||||||
|
G_CREDENTIALS_TYPE_APPLE_XUCRED,
|
||||||
} GCredentialsType;
|
} GCredentialsType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5910,6 +5910,7 @@ g_socket_receive_message (GSocket *socket,
|
|||||||
* - OpenBSD since GLib 2.30
|
* - OpenBSD since GLib 2.30
|
||||||
* - Solaris, Illumos and OpenSolaris since GLib 2.40
|
* - Solaris, Illumos and OpenSolaris since GLib 2.40
|
||||||
* - NetBSD since GLib 2.42
|
* - NetBSD since GLib 2.42
|
||||||
|
* - macOS, tvOS, iOS since GLib 2.66
|
||||||
*
|
*
|
||||||
* Other ways to obtain credentials from a foreign peer includes the
|
* Other ways to obtain credentials from a foreign peer includes the
|
||||||
* #GUnixCredentialsMessage type and
|
* #GUnixCredentialsMessage type and
|
||||||
@ -5951,6 +5952,41 @@ g_socket_get_credentials (GSocket *socket,
|
|||||||
native_creds_buf);
|
native_creds_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
{
|
||||||
|
struct xucred cred;
|
||||||
|
socklen_t optlen = sizeof (cred);
|
||||||
|
|
||||||
|
if (getsockopt (socket->priv->fd,
|
||||||
|
0,
|
||||||
|
LOCAL_PEERCRED,
|
||||||
|
&cred,
|
||||||
|
&optlen) == 0)
|
||||||
|
{
|
||||||
|
if (cred.cr_version == XUCRED_VERSION)
|
||||||
|
{
|
||||||
|
ret = g_credentials_new ();
|
||||||
|
g_credentials_set_native (ret,
|
||||||
|
G_CREDENTIALS_NATIVE_TYPE,
|
||||||
|
&cred);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
/* No point in translating this! */
|
||||||
|
"struct xucred cr_version %u != %u",
|
||||||
|
cred.cr_version, XUCRED_VERSION);
|
||||||
|
/* Reuse a translatable string we already have */
|
||||||
|
g_prefix_error (error,
|
||||||
|
_("Unable to read socket credentials: %s"),
|
||||||
|
"");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
|
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
|
||||||
{
|
{
|
||||||
struct unpcbid cred;
|
struct unpcbid cred;
|
||||||
|
@ -96,6 +96,7 @@ g_unix_credentials_message_get_msg_type (GSocketControlMessage *message)
|
|||||||
#elif G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
|
#elif G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
|
||||||
#error "G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED is set but there is no msg_type defined for this platform"
|
#error "G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED is set but there is no msg_type defined for this platform"
|
||||||
#else
|
#else
|
||||||
|
/* includes G_CREDENTIALS_USE_APPLE_XUCRED */
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,14 @@ test_basic (void)
|
|||||||
g_assert_cmpuint (native->uid, ==, geteuid ());
|
g_assert_cmpuint (native->uid, ==, geteuid ());
|
||||||
g_assert_cmpuint (native->pid, ==, getpid ());
|
g_assert_cmpuint (native->pid, ==, getpid ());
|
||||||
}
|
}
|
||||||
|
#elif G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
{
|
||||||
|
struct xucred *native = g_credentials_get_native (creds,
|
||||||
|
G_CREDENTIALS_TYPE_APPLE_XUCRED);
|
||||||
|
|
||||||
|
g_assert_cmpuint (native->cr_version, ==, XUCRED_VERSION);
|
||||||
|
g_assert_cmpuint (native->cr_uid, ==, geteuid ());
|
||||||
|
}
|
||||||
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
|
||||||
{
|
{
|
||||||
struct cmsgcred *native = g_credentials_get_native (creds,
|
struct cmsgcred *native = g_credentials_get_native (creds,
|
||||||
|
@ -244,6 +244,11 @@ assert_expected_uid_pid (InteropFlags flags,
|
|||||||
* on Linux. */
|
* on Linux. */
|
||||||
g_assert_cmpint (uid, ==, getuid ());
|
g_assert_cmpint (uid, ==, getuid ());
|
||||||
g_assert_cmpint (pid, ==, getpid ());
|
g_assert_cmpint (pid, ==, getpid ());
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
/* We know (or at least suspect) that both GDBus and libdbus support
|
||||||
|
* passing the uid only on macOS. */
|
||||||
|
g_assert_cmpint (uid, ==, getuid ());
|
||||||
|
/* No pid here */
|
||||||
#else
|
#else
|
||||||
g_test_message ("Please open a merge request to add appropriate "
|
g_test_message ("Please open a merge request to add appropriate "
|
||||||
"assertions for your platform");
|
"assertions for your platform");
|
||||||
|
Loading…
Reference in New Issue
Block a user