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>
This commit is contained in:
David Zeuthen
2010-07-20 14:02:14 -04:00
parent b3cf5cbd0b
commit 7eba41346e
13 changed files with 274 additions and 117 deletions

View File

@@ -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;
}