Set up gtk-doc for GDBus

Also move send_credentials() and receive_credentials() to
GUnixConnection. This code might change, discussion is still ongoing
in

 https://bugzilla.gnome.org/show_bug.cgi?id=617483.
This commit is contained in:
David Zeuthen
2010-05-06 15:31:45 -04:00
parent d0a14469d0
commit c490c14f4e
20 changed files with 712 additions and 211 deletions

View File

@@ -36,8 +36,8 @@
/**
* SECTION:gcredentials
* @short_description: Credentials
* @include: gdbus/gdbus.h
* @short_description: An object containing credentials
* @include: gio/gio.h
*
* The #GCredentials type is used for storing information that can be
* used for identifying, authenticating and authorizing processes.

View File

@@ -40,7 +40,7 @@
* SECTION:gdbusaddress
* @title: D-Bus Addresses
* @short_description: D-Bus connection endpoints
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* Routines for working with D-Bus addresses.
*/

View File

@@ -78,195 +78,6 @@ debug_print (const gchar *message, ...)
#endif
}
/* ---------------------------------------------------------------------------------------------------- */
/* TODO: move to gio */
/**
* g_unix_connection_send_credentials:
* @connection: A #GUnixConnection.
* @credentials: A #GCredentials to send.
* @cancellable: A #GCancellable or %NULL.
* @error: Return location for error or %NULL.
*
* Passes the credentials stored in @credentials to the recieving side
* of the connection. The recieving end has to call
* g_unix_connection_receive_credentials() (or similar) to accept the
* credentials.
*
* The credentials which the sender specifies are checked by the
* kernel. A process with effective user ID 0 is allowed to specify
* values that do not match its own. This means that the credentials
* can be used to authenticate other connections.
*
* As well as sending the credentials this also writes a single NUL
* byte to the stream, as this is required for credentials passing to
* work on some implementations.
*
* Returns: %TRUE on success, %FALSE if @error is set.
*
* Since: 2.26
*/
static gboolean
g_unix_connection_send_credentials (GUnixConnection *connection,
GCredentials *credentials,
GCancellable *cancellable,
GError **error)
{
GSocketControlMessage *scm;
GSocket *socket;
gboolean ret;
GOutputVector vector;
guchar nul_byte[1] = {'\0'};
g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE);
g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
ret = FALSE;
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,
&scm,
1,
G_SOCKET_MSG_NONE,
cancellable,
error) != 1)
{
g_prefix_error (error, _("Error sending credentials: "));
goto out;
}
ret = TRUE;
out:
g_object_unref (socket);
g_object_unref (scm);
return ret;
}
/**
* g_unix_connection_receive_credentials:
* @connection: A #GUnixConnection.
* @cancellable: A #GCancellable or %NULL.
* @error: Return location for error or %NULL.
*
* Receives credentials from the sending end of the connection. The
* sending end has to call g_unix_connection_send_credentials() (or
* similar) for this to work.
*
* As well as reading the credentials this also reads (and discards) a
* single byte from the stream, as this is required for credentials
* passing to work on some implementations.
*
* Returns: Received credentials on success (free with
* g_object_unref()), %NULL if @error is set.
*
* Since: 2.26
*/
static GCredentials *
g_unix_connection_receive_credentials (GUnixConnection *connection,
GCancellable *cancellable,
GError **error)
{
GCredentials *ret;
GSocketControlMessage **scms;
gint nscm;
GSocket *socket;
gint n;
volatile GType credentials_message_gtype;
gssize num_bytes_read;
g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
ret = NULL;
scms = NULL;
g_object_get (connection, "socket", &socket, NULL);
#if 1
/* TODO: Move this to gsocket.c... */
{
int opt_val = 1;
if (setsockopt (g_socket_get_fd (socket),
SOL_SOCKET,
SO_PASSCRED,
&opt_val,
sizeof opt_val) != 0)
{
g_warning ("boo, error setting SO_PASSCRED: %m");
}
}
#endif
/* ensure the type of GUnixCredentialsMessage has been registered with the type system */
credentials_message_gtype = G_TYPE_UNIX_CREDENTIALS_MESSAGE;
num_bytes_read = g_socket_receive_message (socket,
NULL, /* GSocketAddress **address */
NULL,
0,
&scms,
&nscm,
NULL,
cancellable,
error);
if (num_bytes_read != 1)
{
/* Handle situation where g_socket_receive_message() returns
* 0 bytes and not setting @error
*/
if (num_bytes_read == 0 && error != NULL && *error == NULL)
{
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Expecting to read a single byte for receiving credentials but read zero bytes"));
}
goto out;
}
if (nscm != 1)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Expecting 1 control message, got %d"),
nscm);
goto out;
}
if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0]))
{
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Unexpected type of ancillary data"));
goto out;
}
ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0]));
g_object_ref (ret);
out:
if (scms != NULL)
{
for (n = 0; n < nscm; n++)
g_object_unref (scms[n]);
g_free (scms);
}
g_object_unref (socket);
return ret;
}
/* ---------------------------------------------------------------------------------------------------- */
typedef struct
{
const gchar *name;

View File

@@ -33,7 +33,7 @@
/**
* SECTION:gdbusauthobserver
* @short_description: Object used for authenticating connections
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* The #GDBusAuthObserver type provides a mechanism for participating
* in how a #GDBusServer (or a #GDBusConnection) authenticates remote

View File

@@ -78,7 +78,7 @@
/**
* SECTION:gdbusconnection
* @short_description: D-Bus Connections
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* <para><note>
* This class is rarely used directly in D-Bus clients. If you are
@@ -89,11 +89,11 @@
* The #GDBusConnection type is used for D-Bus connections to remote
* peers such as a message buses.
*
* <example id="gdbus-server"><title>D-Bus server example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-server.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
* <example id="gdbus-server"><title>D-Bus server example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-server.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*
* <example id="gdbus-subtree-server"><title>D-Bus subtree example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-subtree.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
* <example id="gdbus-subtree-server"><title>D-Bus subtree example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-subtree.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*
* <example id="gdbus-unix-fd-client"><title>D-Bus UNIX File Descriptor example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-unix-fd-client.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
* <example id="gdbus-unix-fd-client"><title>D-Bus UNIX File Descriptor example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-unix-fd-client.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
/* ---------------------------------------------------------------------------------------------------- */

View File

@@ -36,7 +36,7 @@
* SECTION:gdbuserror
* @title: GDBusError
* @short_description: Mapping D-Bus errors to and from #GError
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* All facilities that return errors from remote methods (such as
* g_dbus_connection_invoke_method_sync()) use #GError to represent

View File

@@ -32,7 +32,7 @@
* SECTION:gdbusintrospection
* @title: Introspection XML
* @short_description: Parse and Generate Introspection XML
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* Various data structures and convenience routines to parse and
* generate D-Bus introspection XML.

View File

@@ -48,7 +48,7 @@
/**
* SECTION:gdbusmessage
* @short_description: D-Bus Message
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* A type for representing D-Bus messages that can be sent or received
* on a #GDBusConnection.

View File

@@ -36,7 +36,7 @@
/**
* SECTION:gdbusmethodinvocation
* @short_description: Object for handling remote calls
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* Instances of the #GDBusMethodInvocation class are used when
* handling D-Bus method calls. It provides a way to asynchronously

View File

@@ -36,11 +36,11 @@
* SECTION:gdbusnameowning
* @title: Owning Bus Names
* @short_description: Simple API for owning bus names
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* Convenience API for owning bus names.
*
* <example id="gdbus-owning-names"><title>Simple application owning a name</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-own-name.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
* <example id="gdbus-owning-names"><title>Simple application owning a name</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-own-name.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
G_LOCK_DEFINE_STATIC (lock);

View File

@@ -36,11 +36,11 @@
* SECTION:gdbusnamewatching
* @title: Watching Bus Names
* @short_description: Simple API for watching bus names
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* Convenience API for watching bus names.
*
* <example id="gdbus-watching-names"><title>Simple application watching a name</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-watch-name.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
* <example id="gdbus-watching-names"><title>Simple application watching a name</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-watch-name.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
G_LOCK_DEFINE_STATIC (lock);

View File

@@ -42,7 +42,7 @@
/**
* SECTION:gdbusproxy
* @short_description: Base class for proxies
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* #GDBusProxy is a base class used for proxies to access a D-Bus
* interface on a remote object. A #GDBusProxy can only be constructed

View File

@@ -39,11 +39,11 @@
* SECTION:gdbusproxywatching
* @title: Watching Proxies
* @short_description: Simple API for watching proxies
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* Convenience API for watching bus proxies.
*
* <example id="gdbus-watching-proxy"><title>Simple application watching a proxy</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-watch-proxy.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
* <example id="gdbus-watching-proxy"><title>Simple application watching a proxy</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-watch-proxy.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
/* ---------------------------------------------------------------------------------------------------- */

View File

@@ -44,12 +44,12 @@
/**
* SECTION:gdbusserver
* @short_description: Helper for accepting connections
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* #GDBusServer is a helper for listening to and accepting D-Bus
* connections.
*
* <example id="gdbus-peer-to-peer"><title>D-Bus peer-to-peer example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-peer.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
* <example id="gdbus-peer-to-peer"><title>D-Bus peer-to-peer example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-peer.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
struct _GDBusServerPrivate

View File

@@ -33,7 +33,7 @@
* SECTION:gdbusutils
* @title: D-Bus Utilities
* @short_description: Various utilities related to D-Bus.
* @include: gdbus/gdbus.h
* @include: gio/gio.h
*
* Various utility routines related to D-Bus.
*/

View File

@@ -36,6 +36,14 @@
#include <gio/gsocket.h>
#include <unistd.h>
#ifdef __linux__
/* for getsockopt() and setsockopt() */
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#endif
#include "gioalias.h"
G_DEFINE_TYPE_WITH_CODE (GUnixConnection, g_unix_connection,
@@ -287,5 +295,255 @@ gboolean g_unix_connection_create_pair (GUnixCo
GError **error);
*/
/**
* g_unix_connection_send_credentials:
* @connection: A #GUnixConnection.
* @credentials: A #GCredentials to send.
* @cancellable: A #GCancellable or %NULL.
* @error: Return location for error or %NULL.
*
* Passes the credentials stored in @credentials to the recieving side
* of the connection. The recieving end has to call
* g_unix_connection_receive_credentials() (or similar) to accept the
* credentials.
*
* The credentials which the sender specifies are checked by the
* kernel. A process with effective user ID 0 is allowed to specify
* values that do not match its own. This means that the credentials
* can be used to authenticate other connections.
*
* As well as sending the credentials this also writes a single NUL
* byte to the stream, as this is required for credentials passing to
* work on some implementations.
*
* Returns: %TRUE on success, %FALSE if @error is set.
*
* Since: 2.26
*/
gboolean
g_unix_connection_send_credentials (GUnixConnection *connection,
GCredentials *credentials,
GCancellable *cancellable,
GError **error)
{
GSocketControlMessage *scm;
GSocket *socket;
gboolean ret;
GOutputVector vector;
guchar nul_byte[1] = {'\0'};
g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE);
g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
ret = FALSE;
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,
&scm,
1,
G_SOCKET_MSG_NONE,
cancellable,
error) != 1)
{
g_prefix_error (error, _("Error sending credentials: "));
goto out;
}
ret = TRUE;
out:
g_object_unref (socket);
g_object_unref (scm);
return ret;
}
/**
* g_unix_connection_receive_credentials:
* @connection: A #GUnixConnection.
* @cancellable: A #GCancellable or %NULL.
* @error: Return location for error or %NULL.
*
* Receives credentials from the sending end of the connection. The
* sending end has to call g_unix_connection_send_credentials() (or
* similar) for this to work.
*
* As well as reading the credentials this also reads (and discards) a
* single byte from the stream, as this is required for credentials
* passing to work on some implementations.
*
* Returns: Received credentials on success (free with
* g_object_unref()), %NULL if @error is set.
*
* Since: 2.26
*/
GCredentials *
g_unix_connection_receive_credentials (GUnixConnection *connection,
GCancellable *cancellable,
GError **error)
{
GCredentials *ret;
GSocketControlMessage **scms;
gint nscm;
GSocket *socket;
gint n;
volatile GType credentials_message_gtype;
gssize num_bytes_read;
#ifdef __linux__
gboolean turn_off_so_passcreds;
#endif
g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
ret = NULL;
scms = NULL;
g_object_get (connection, "socket", &socket, NULL);
/* On Linux, we need to turn on SO_PASSCRED if it isn't enabled
* already. We also need to turn it off when we're done. See
* #617483 for more discussion.
*/
#ifdef __linux__
{
gint opt_val;
socklen_t opt_len;
turn_off_so_passcreds = FALSE;
opt_val = 0;
opt_len = sizeof (gint);
if (getsockopt (g_socket_get_fd (socket),
SOL_SOCKET,
SO_PASSCRED,
&opt_val,
&opt_len) != 0)
{
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
_("Error checking if SO_PASSCRED is enabled for socket: %s"),
strerror (errno));
goto out;
}
if (opt_len != sizeof (gint))
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Unexpected option length while checking if SO_PASSCRED is enabled for socket. "
"Expected %d bytes, got %d"),
(gint) sizeof (gint), (gint) opt_len);
goto out;
}
if (opt_val == 0)
{
opt_val = 1;
if (setsockopt (g_socket_get_fd (socket),
SOL_SOCKET,
SO_PASSCRED,
&opt_val,
sizeof opt_val) != 0)
{
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
_("Error enabling SO_PASSCRED: %s"),
strerror (errno));
goto out;
}
turn_off_so_passcreds = TRUE;
}
}
#endif
/* ensure the type of GUnixCredentialsMessage has been registered with the type system */
credentials_message_gtype = G_TYPE_UNIX_CREDENTIALS_MESSAGE;
num_bytes_read = g_socket_receive_message (socket,
NULL, /* GSocketAddress **address */
NULL,
0,
&scms,
&nscm,
NULL,
cancellable,
error);
if (num_bytes_read != 1)
{
/* Handle situation where g_socket_receive_message() returns
* 0 bytes and not setting @error
*/
if (num_bytes_read == 0 && error != NULL && *error == NULL)
{
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Expecting to read a single byte for receiving credentials but read zero bytes"));
}
goto out;
}
if (nscm != 1)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Expecting 1 control message, got %d"),
nscm);
goto out;
}
if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0]))
{
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
_("Unexpected type of ancillary data"));
goto out;
}
ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0]));
g_object_ref (ret);
out:
#ifdef __linux__
if (turn_off_so_passcreds)
{
gint opt_val;
opt_val = 0;
if (setsockopt (g_socket_get_fd (socket),
SOL_SOCKET,
SO_PASSCRED,
&opt_val,
sizeof opt_val) != 0)
{
g_set_error (error,
G_IO_ERROR,
g_io_error_from_errno (errno),
_("Error while disabling SO_PASSCRED: %s"),
strerror (errno));
goto out;
}
}
#endif
if (scms != NULL)
{
for (n = 0; n < nscm; n++)
g_object_unref (scms[n]);
g_free (scms);
}
g_object_unref (socket);
return ret;
}
#define __G_UNIX_CONNECTION_C__
#include "gioaliasdef.c"

View File

@@ -71,6 +71,16 @@ gint g_unix_connection_receive_fd (GUnixCo
GCancellable *cancellable,
GError **error);
gboolean g_unix_connection_send_credentials (GUnixConnection *connection,
GCredentials *credentials,
GCancellable *cancellable,
GError **error);
GCredentials *g_unix_connection_receive_credentials (GUnixConnection *connection,
GCancellable *cancellable,
GError **error);
G_END_DECLS
#endif /* __G_UNIX_CONNECTION_H__ */