[glib] Bug 617483 – Credentials passing
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Bug 617483 – Credentials passing
- Date: Tue, 20 Jul 2010 20:44:37 +0000 (UTC)
commit 7eba41346e014649d8f9cf8ab675d1f091f7cf38
Author: David Zeuthen <davidz redhat com>
Date: Tue Jul 20 14:02:14 2010 -0400
Bug 617483 â?? Credentials passing
- Make GCredentials instance and class structures private so it can't
be subclassed and we don't have to worry about ABI compat
issues. This also allows us to get rid of the GCredentialsPrivate
struct.
- Add a GCredentialsType enumeration that is used whenever exchanging
pointers with the user. This allows us to support OSes with
multiple native credential types. In particular, it allows
supporting OSes where the native credential evolves or even changes
over time.
- Add g_socket_get_credentials() method.
- Add tests for g_socket_get_credentials(). Right now this is in the
GDBus peer-to-peer test case but we can change that later.
- Move GTcpConnection into a separate gtk-doc page as was already
half-done with GUnixConnection. Also finish the GUnixConnection
move and ensure send_credentials() and receive_credentials()
methods are in the docs. Also nuke comment about GTcpConnection
being empty compared to its superclass.
Signed-off-by: David Zeuthen <davidz redhat com>
docs/reference/gio/gio-docs.xml | 1 +
docs/reference/gio/gio-sections.txt | 43 ++++++-----
gio/gcredentials.c | 135 ++++++++++++++++++++++++-----------
gio/gcredentials.h | 44 +----------
gio/gio.symbols | 2 +
gio/gioenums.h | 15 ++++
gio/gnetworkingprivate.h | 8 ++
gio/gsocket.c | 72 ++++++++++++++++++-
gio/gsocket.h | 2 +
gio/gtcpconnection.c | 7 +--
gio/gunixconnection.c | 6 ++
gio/gunixcredentialsmessage.c | 18 +++--
gio/tests/gdbus-peer.c | 36 +++++++++
13 files changed, 273 insertions(+), 116 deletions(-)
---
diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml
index fefa7f8..b86ad9a 100644
--- a/docs/reference/gio/gio-docs.xml
+++ b/docs/reference/gio/gio-docs.xml
@@ -115,6 +115,7 @@
<xi:include href="xml/gsocketclient.xml"/>
<xi:include href="xml/gsocketconnection.xml"/>
<xi:include href="xml/gunixconnection.xml"/>
+ <xi:include href="xml/gtcpconnection.xml"/>
<xi:include href="xml/gsocketlistener.xml"/>
<xi:include href="xml/gsocketservice.xml"/>
<xi:include href="xml/gthreadedsocketservice.xml"/>
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 0ea89c4..00105e6 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -1741,6 +1741,7 @@ g_socket_get_protocol
g_socket_get_remote_address
g_socket_get_socket_type
g_socket_speaks_ipv4
+g_socket_get_credentials
<SUBSECTION Standard>
GSocketClass
G_IS_SOCKET
@@ -1797,16 +1798,6 @@ g_socket_connection_get_local_address
g_socket_connection_get_remote_address
g_socket_connection_get_socket
<SUBSECTION>
-GTcpConnection
-g_tcp_connection_set_graceful_disconnect
-g_tcp_connection_get_graceful_disconnect
-<SUBSECTION>
-GUnixConnection
-g_unix_connection_receive_fd
-g_unix_connection_send_fd
-g_unix_connection_receive_credentials
-g_unix_connection_send_credentials
-<SUBSECTION>
g_socket_connection_factory_create_connection
g_socket_connection_factory_lookup_type
g_socket_connection_factory_register_type
@@ -1818,18 +1809,9 @@ G_SOCKET_CONNECTION
G_SOCKET_CONNECTION_CLASS
G_SOCKET_CONNECTION_GET_CLASS
G_TYPE_SOCKET_CONNECTION
-GTcpConnectionClass
-G_IS_TCP_CONNECTION
-G_IS_TCP_CONNECTION_CLASS
-G_TCP_CONNECTION
-G_TCP_CONNECTION_CLASS
-G_TCP_CONNECTION_GET_CLASS
-G_TYPE_TCP_CONNECTION
<SUBSECTION Private>
GSocketConnectionPrivate
g_socket_connection_get_type
-GTcpConnectionPrivate
-g_tcp_connection_get_type
</SECTION>
<SECTION>
@@ -1838,6 +1820,8 @@ g_tcp_connection_get_type
GUnixConnection
g_unix_connection_receive_fd
g_unix_connection_send_fd
+g_unix_connection_receive_credentials
+g_unix_connection_send_credentials
<SUBSECTION Standard>
GUnixConnectionClass
G_IS_UNIX_CONNECTION
@@ -1852,6 +1836,25 @@ g_unix_connection_get_type
</SECTION>
<SECTION>
+<FILE>gtcpconnection</FILE>
+<TITLE>GTcpConnection</TITLE>
+GTcpConnection
+g_tcp_connection_set_graceful_disconnect
+g_tcp_connection_get_graceful_disconnect
+<SUBSECTION Standard>
+GTcpConnectionClass
+G_IS_TCP_CONNECTION
+G_IS_TCP_CONNECTION_CLASS
+G_TYPE_TCP_CONNECTION
+G_TCP_CONNECTION
+G_TCP_CONNECTION_CLASS
+G_TCP_CONNECTION_GET_CLASS
+<SUBSECTION Private>
+GTcpConnectionPrivate
+g_tcp_connection_get_type
+</SECTION>
+
+<SECTION>
<FILE>gsocketcontrolmessage</FILE>
<TITLE>GSocketControlMessage</TITLE>
GSocketControlMessage
@@ -2210,7 +2213,7 @@ g_unix_credentials_message_get_type
<FILE>gcredentials</FILE>
<TITLE>GCredentials</TITLE>
GCredentials
-GCredentialsClass
+GCredentialsType
g_credentials_new
g_credentials_to_string
g_credentials_get_native
diff --git a/gio/gcredentials.c b/gio/gcredentials.c
index 5b8119d..e79901f 100644
--- a/gio/gcredentials.c
+++ b/gio/gcredentials.c
@@ -24,17 +24,10 @@
#include <stdlib.h>
-#ifdef __linux__
-#define __USE_GNU
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <string.h>
-#endif
-
#include <gobject/gvaluecollector.h>
#include "gcredentials.h"
+#include "gnetworkingprivate.h"
#include "gioerror.h"
#include "glibintl.h"
@@ -44,9 +37,9 @@
* @short_description: An object containing credentials
* @include: gio/gio.h
*
- * The #GCredentials type is a reference-counted wrapper for the
- * native credentials type. This information is typically used for
- * identifying, authenticating and authorizing other processes.
+ * The #GCredentials type is a reference-counted wrapper for native
+ * credentials. This information is typically used for identifying,
+ * authenticating and authorizing other processes.
*
* Some operating systems supports looking up the credentials of the
* remote peer of a communication endpoint - see e.g.
@@ -57,22 +50,48 @@
* #GUnixCredentialsMessage, g_unix_connection_send_credentials() and
* g_unix_connection_receive_credentials() for details.
*
- * On Linux, the native credential type is a <literal>struct ucred</literal> - see
- * the <literal>unix(7)</literal> man page for details.
+ * On Linux, the native credential type is a <type>struct ucred</type>
+ * - see the
+ * <citerefentry><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ * man page for details. This corresponds to
+ * %G_CREDENTIALS_TYPE_LINUX_UCRED.
*/
-struct _GCredentialsPrivate
+/**
+ * GCredentials:
+ *
+ * The #GCredentials structure contains only private data and
+ * should only be accessed using the provided API.
+ *
+ * Since: 2.26
+ */
+struct _GCredentials
{
+ /*< private >*/
+ GObject parent_instance;
+
#ifdef __linux__
struct ucred native;
#else
#ifdef __GNUC__
#warning Please add GCredentials support for your OS
#endif
- guint foo;
#endif
};
+/**
+ * GCredentialsClass:
+ *
+ * Class structure for #GCredentials.
+ *
+ * Since: 2.26
+ */
+struct _GCredentialsClass
+{
+ /*< private >*/
+ GObjectClass parent_class;
+};
+
G_DEFINE_TYPE (GCredentials, g_credentials, G_TYPE_OBJECT);
static void
@@ -90,8 +109,6 @@ g_credentials_class_init (GCredentialsClass *klass)
{
GObjectClass *gobject_class;
- g_type_class_add_private (klass, sizeof (GCredentialsPrivate));
-
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = g_credentials_finalize;
}
@@ -99,11 +116,10 @@ g_credentials_class_init (GCredentialsClass *klass)
static void
g_credentials_init (GCredentials *credentials)
{
- credentials->priv = G_TYPE_INSTANCE_GET_PRIVATE (credentials, G_TYPE_CREDENTIALS, GCredentialsPrivate);
#ifdef __linux__
- credentials->priv->native.pid = getpid ();
- credentials->priv->native.uid = getuid ();
- credentials->priv->native.gid = getgid ();
+ credentials->native.pid = getpid ();
+ credentials->native.uid = getuid ();
+ credentials->native.gid = getgid ();
#endif
}
@@ -148,13 +164,13 @@ g_credentials_to_string (GCredentials *credentials)
ret = g_string_new ("GCredentials:");
#ifdef __linux__
- g_string_append (ret, "linux:");
- if (credentials->priv->native.pid != -1)
- g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->priv->native.pid);
- if (credentials->priv->native.uid != -1)
- g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->priv->native.uid);
- if (credentials->priv->native.gid != -1)
- g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->priv->native.gid);
+ g_string_append (ret, "linux-ucred:");
+ if (credentials->native.pid != -1)
+ g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
+ if (credentials->native.uid != -1)
+ g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.uid);
+ if (credentials->native.gid != -1)
+ g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.gid);
if (ret->str[ret->len - 1] == ',')
ret->str[ret->len - 1] = '\0';
#else
@@ -195,7 +211,7 @@ g_credentials_is_same_user (GCredentials *credentials,
ret = FALSE;
#ifdef __linux__
- if (credentials->priv->native.uid == other_credentials->priv->native.uid)
+ if (credentials->native.uid == other_credentials->native.uid)
ret = TRUE;
#else
g_set_error_literal (error,
@@ -210,25 +226,46 @@ g_credentials_is_same_user (GCredentials *credentials,
/**
* g_credentials_get_native:
* @credentials: A #GCredentials.
+ * @native_type: The type of native credentials to get.
*
- * Gets a pointer to the native credentials structure.
- *
- * Returns: The pointer or %NULL if there is no #GCredentials support
- * for the OS. Do not free the returned data, it is owned by
+ * Gets a pointer to native credentials of type @native_type from
* @credentials.
*
+ * It is a programming error (which will cause an warning to be
+ * logged) to use this method if there is no #GCredentials support for
+ * the OS or if @native_type isn't supported by the OS.
+ *
+ * Returns: The pointer to native credentials or %NULL if the
+ * operation there is no #GCredentials support for the OS or if
+ * @native_type isn't supported by the OS. Do not free the returned
+ * data, it is owned by @credentials.
+ *
* Since: 2.26
*/
gpointer
-g_credentials_get_native (GCredentials *credentials)
+g_credentials_get_native (GCredentials *credentials,
+ GCredentialsType native_type)
{
gpointer ret;
+
g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
+ ret = NULL;
+
#ifdef __linux__
- ret = &credentials->priv->native;
+ if (native_type != G_CREDENTIALS_TYPE_LINUX_UCRED)
+ {
+ g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
+ "G_CREDENTIALS_TYPE_LINUX_UCRED is supported.",
+ native_type);
+ }
+ else
+ {
+ ret = &credentials->native;
+ }
#else
- ret = NULL;
+ g_warning ("g_credentials_get_native: Trying to get credentials but GLib has no support "
+ "for the native credentials type. Please add support.");
#endif
return ret;
@@ -237,22 +274,34 @@ g_credentials_get_native (GCredentials *credentials)
/**
* g_credentials_set_native:
* @credentials: A #GCredentials.
+ * @native_type: The type of native credentials to set.
* @native: A pointer to native credentials.
*
- * Copies the native credentials from @native into @credentials.
+ * Copies the native credentials of type @native_type from @native
+ * into @credentials.
*
* It is a programming error (which will cause an warning to be
* logged) to use this method if there is no #GCredentials support for
- * the OS.
+ * the OS or if @native_type isn't supported by the OS.
*
* Since: 2.26
*/
void
-g_credentials_set_native (GCredentials *credentials,
- gpointer native)
+g_credentials_set_native (GCredentials *credentials,
+ GCredentialsType native_type,
+ gpointer native)
{
#ifdef __linux__
- memcpy (&credentials->priv->native, native, sizeof (struct ucred));
+ if (native_type != G_CREDENTIALS_TYPE_LINUX_UCRED)
+ {
+ g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
+ "but only G_CREDENTIALS_TYPE_LINUX_UCRED is supported.",
+ native_type);
+ }
+ else
+ {
+ memcpy (&credentials->native, native, sizeof (struct ucred));
+ }
#else
g_warning ("g_credentials_set_native: Trying to set credentials but GLib has no support "
"for the native credentials type. Please add support.");
@@ -288,7 +337,7 @@ g_credentials_get_unix_user (GCredentials *credentials,
g_return_val_if_fail (error == NULL || *error == NULL, -1);
#ifdef __linux__
- ret = credentials->priv->native.uid;
+ ret = credentials->native.uid;
#else
ret = -1;
g_set_error_literal (error,
@@ -330,7 +379,7 @@ g_credentials_set_unix_user (GCredentials *credentials,
ret = FALSE;
#ifdef __linux__
- credentials->priv->native.uid = uid;
+ credentials->native.uid = uid;
ret = TRUE;
#else
g_set_error_literal (error,
diff --git a/gio/gcredentials.h b/gio/gcredentials.h
index e0d8fcd..8e09f77 100644
--- a/gio/gcredentials.h
+++ b/gio/gcredentials.h
@@ -45,45 +45,6 @@ G_BEGIN_DECLS
#define G_IS_CREDENTIALS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CREDENTIALS))
typedef struct _GCredentialsClass GCredentialsClass;
-typedef struct _GCredentialsPrivate GCredentialsPrivate;
-
-/**
- * GCredentials:
- *
- * The #GCredentials structure contains only private data and
- * should only be accessed using the provided API.
- *
- * Since: 2.26
- */
-struct _GCredentials
-{
- /*< private >*/
- GObject parent_instance;
- GCredentialsPrivate *priv;
-};
-
-/**
- * GCredentialsClass:
- *
- * Class structure for #GCredentials.
- *
- * Since: 2.26
- */
-struct _GCredentialsClass
-{
- /*< private >*/
- GObjectClass parent_class;
-
- /* Padding for future expansion */
- void (*_g_reserved1) (void);
- void (*_g_reserved2) (void);
- void (*_g_reserved3) (void);
- void (*_g_reserved4) (void);
- void (*_g_reserved5) (void);
- void (*_g_reserved6) (void);
- void (*_g_reserved7) (void);
- void (*_g_reserved8) (void);
-};
GType g_credentials_get_type (void) G_GNUC_CONST;
@@ -91,8 +52,11 @@ GCredentials *g_credentials_new (void);
gchar *g_credentials_to_string (GCredentials *credentials);
-gpointer g_credentials_get_native (GCredentials *credentials);
+gpointer g_credentials_get_native (GCredentials *credentials,
+ GCredentialsType native_type);
+
void g_credentials_set_native (GCredentials *credentials,
+ GCredentialsType native_type,
gpointer native);
gboolean g_credentials_is_same_user (GCredentials *credentials,
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 1ca38bd..11d0372 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -1025,6 +1025,7 @@ g_dbus_subtree_flags_get_type G_GNUC_CONST
g_dbus_server_flags_get_type G_GNUC_CONST
g_dbus_signal_flags_get_type G_GNUC_CONST
g_dbus_send_message_flags_get_type G_GNUC_CONST
+g_credentials_type_get_type G_GNUC_CONST
#endif
#endif
@@ -1264,6 +1265,7 @@ g_socket_set_timeout
g_socket_set_keepalive
g_socket_set_listen_backlog
g_socket_speaks_ipv4
+g_socket_get_credentials
#endif
#endif
diff --git a/gio/gioenums.h b/gio/gioenums.h
index e91f37c..8d5f330 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -1169,6 +1169,21 @@ typedef enum
G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL = (1<<0)
} GDBusSendMessageFlags;
+/**
+ * GCredentialsType:
+ * @G_CREDENTIALS_TYPE_INVALID: Indicates an invalid native credential type.
+ * @G_CREDENTIALS_TYPE_LINUX_UCRED: The native credentials type is a <type>struct ucred</type>.
+ *
+ * Enumeration describing different kinds of native credential types.
+ *
+ * Since: 2.26
+ */
+typedef enum
+{
+ G_CREDENTIALS_TYPE_INVALID,
+ G_CREDENTIALS_TYPE_LINUX_UCRED
+} GCredentialsType;
+
G_END_DECLS
#endif /* __GIO_ENUMS_H__ */
diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h
index 9cbb55d..dcfba0d 100644
--- a/gio/gnetworkingprivate.h
+++ b/gio/gnetworkingprivate.h
@@ -40,6 +40,14 @@
#else /* !G_OS_WIN32 */
+/* need this for struct ucred on Linux */
+#ifdef __linux__
+#define __USE_GNU
+#include <sys/types.h>
+#include <sys/socket.h>
+#undef __USE_GNU
+#endif
+
#include <sys/types.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 5ab7778..fbb8974 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -53,9 +53,9 @@
#include "gnetworkingprivate.h"
#include "gsocketaddress.h"
#include "gsocketcontrolmessage.h"
+#include "gcredentials.h"
#include "glibintl.h"
-
/**
* SECTION:gsocket
* @short_description: Low-level socket object
@@ -3321,3 +3321,73 @@ g_socket_receive_message (GSocket *socket,
}
#endif
}
+
+/**
+ * g_socket_get_credentials:
+ * @socket: a #GSocket.
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * Returns the credentials of the foreign process connected to this
+ * socket, if any (e.g. it is only supported for %G_SOCKET_FAMILY_UNIX
+ * sockets).
+ *
+ * If this operation isn't supported on the OS, the method fails with
+ * the %G_IO_ERROR_NOT_SUPPORTED error. On Linux this is implemented
+ * by reading the %SO_PEERCRED option on the underlying socket.
+ *
+ * Other ways to obtain credentials from a foreign peer includes the
+ * #GUnixCredentialsMessage type and
+ * g_unix_connection_send_credentials() /
+ * g_unix_connection_receive_credentials() functions.
+ *
+ * Returns: %NULL if @error is set, otherwise a #GCredentials object
+ * that must be freed with g_object_unref().
+ *
+ * Since: 2.26
+ */
+GCredentials *
+g_socket_get_credentials (GSocket *socket,
+ GError **error)
+{
+ GCredentials *ret;
+
+ g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ ret = NULL;
+
+#ifdef __linux__
+ {
+ struct ucred native_creds;
+ socklen_t optlen;
+ optlen = sizeof (struct ucred);
+ if (getsockopt (socket->priv->fd,
+ SOL_SOCKET,
+ SO_PEERCRED,
+ (void *)&native_creds,
+ &optlen) != 0)
+ {
+ int errsv = get_socket_errno ();
+ g_set_error (error,
+ G_IO_ERROR,
+ socket_io_error_from_errno (errsv),
+ _("Unable to get pending error: %s"),
+ socket_strerror (errsv));
+ }
+ else
+ {
+ ret = g_credentials_new ();
+ g_credentials_set_native (ret,
+ G_CREDENTIALS_TYPE_LINUX_UCRED,
+ &native_creds);
+ }
+ }
+#else
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("g_socket_get_credentials not implemented for this OS"));
+#endif
+
+ return ret;
+}
diff --git a/gio/gsocket.h b/gio/gsocket.h
index 350cc28..b2476cc 100644
--- a/gio/gsocket.h
+++ b/gio/gsocket.h
@@ -173,6 +173,8 @@ GSource * g_socket_create_source (GSocket
GIOCondition condition,
GCancellable *cancellable);
gboolean g_socket_speaks_ipv4 (GSocket *socket);
+GCredentials *g_socket_get_credentials (GSocket *socket,
+ GError **error);
G_END_DECLS
diff --git a/gio/gtcpconnection.c b/gio/gtcpconnection.c
index 15e1a9a..89aeaba 100644
--- a/gio/gtcpconnection.c
+++ b/gio/gtcpconnection.c
@@ -13,17 +13,12 @@
/**
* SECTION: gtcpconnection
* @title: GTcpConnection
- * @short_description: a TCP #GSocketConnection
+ * @short_description: a TCP GSocketConnection
* @see_also: #GSocketConnection.
*
* This is the subclass of #GSocketConnection that is created
* for TCP/IP sockets.
*
- * It is currently empty; it offers no additional functionality
- * over its base class.
- *
- * Eventually, some TCP-specific socket stuff will be added.
- *
* Since: 2.22
*/
diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c
index b5cf136..d5da2a0 100644
--- a/gio/gunixconnection.c
+++ b/gio/gunixconnection.c
@@ -316,6 +316,9 @@ gboolean g_unix_connection_create_pair (GUnixCo
* byte to the stream, as this is required for credentials passing to
* work on some implementations.
*
+ * Other ways to exchange credentials with a foreign peer includes the
+ * #GUnixCredentialsMessage type and g_socket_get_credentials() function.
+ *
* Note that this function only works on Linux, currently.
*
* Returns: %TRUE on success, %FALSE if @error is set.
@@ -382,6 +385,9 @@ g_unix_connection_send_credentials (GUnixConnection *connection,
* single byte from the stream, as this is required for credentials
* passing to work on some implementations.
*
+ * Other ways to exchange credentials with a foreign peer includes the
+ * #GUnixCredentialsMessage type and g_socket_get_credentials() function.
+ *
* Returns: Received credentials on success (free with
* g_object_unref()), %NULL if @error is set.
*
diff --git a/gio/gunixcredentialsmessage.c b/gio/gunixcredentialsmessage.c
index 12b2490..e6dadfb 100644
--- a/gio/gunixcredentialsmessage.c
+++ b/gio/gunixcredentialsmessage.c
@@ -23,12 +23,15 @@
* This #GSocketControlMessage contains a #GCredentials instance. It
* may be sent using g_socket_send_message() and received using
* g_socket_receive_message() over UNIX sockets (ie: sockets in the
- * %G_SOCKET_ADDRESS_UNIX family).
+ * %G_SOCKET_FAMILY_UNIX family).
*
* For an easier way to send and receive credentials over
- * stream-oriented UNIX sockets, see g_unix_connection_send_credentials() and
- * g_unix_connection_receive_credentials().
- **/
+ * stream-oriented UNIX sockets, see
+ * g_unix_connection_send_credentials() and
+ * g_unix_connection_receive_credentials(). To receive credentials of
+ * a foreign process connected to a socket, use
+ * g_socket_get_credentials().
+ */
#include "config.h"
@@ -131,7 +134,7 @@ g_unix_credentials_message_deserialize (gint level,
ucred = data;
credentials = g_credentials_new ();
- g_credentials_set_native (credentials, ucred);
+ g_credentials_set_native (credentials, G_CREDENTIALS_TYPE_LINUX_UCRED, ucred);
message = g_unix_credentials_message_new_with_credentials (credentials);
g_object_unref (credentials);
out:
@@ -148,7 +151,10 @@ g_unix_credentials_message_serialize (GSocketControlMessage *_message,
{
GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (_message);
#ifdef __linux__
- memcpy (data, g_credentials_get_native (message->priv->credentials), sizeof (struct ucred));
+ memcpy (data,
+ g_credentials_get_native (message->priv->credentials,
+ G_CREDENTIALS_TYPE_LINUX_UCRED),
+ sizeof (struct ucred));
#endif
}
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index 26ed156..f27ca06 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -35,6 +35,13 @@
#include <gio/gunixsocketaddress.h>
#include <gio/gunixfdlist.h>
+/* for struct ucred */
+#ifdef __linux__
+#define __USE_GNU
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif
+
#include "gdbus-tests.h"
@@ -703,6 +710,35 @@ test_peer (void)
g_error_free (error);
#endif /* G_OS_UNIX */
+ /* Check that g_socket_get_credentials() work - this really should
+ * be in a GSocket-specific test suite but no such test suite exists
+ * right now.
+ */
+ {
+ GSocket *socket;
+ GCredentials *credentials;
+ socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (g_dbus_connection_get_stream (c)));
+ g_assert (G_IS_SOCKET (socket));
+ error = NULL;
+ credentials = g_socket_get_credentials (socket, &error);
+#ifdef __linux__
+ {
+ struct ucred *native_creds;
+ g_assert_no_error (error);
+ g_assert (G_IS_CREDENTIALS (credentials));
+ native_creds = g_credentials_get_native (credentials, G_CREDENTIALS_TYPE_LINUX_UCRED);
+ g_assert (native_creds != NULL);
+ g_assert (native_creds->uid == getuid ());
+ g_assert (native_creds->gid == getgid ());
+ g_assert (native_creds->pid == getpid ());
+ }
+ g_object_unref (credentials);
+#else
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
+ g_assert (credentials == NULL);
+#endif
+ }
+
/* bring up a connection - don't accept it - this should fail
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]