[glib] gcredentials: add internal macros to simplify all the #ifdefs



commit cedd697bf80faf18d0d42b3e4d8bef5a5cf8ef9f
Author: Dan Winship <danw gnome org>
Date:   Wed Sep 18 13:40:09 2013 -0400

    gcredentials: add internal macros to simplify all the #ifdefs
    
    Rather than having lots of obscure platform-based #ifdefs all over
    gio, define some macros in gcredentialsprivate.h, and use those to
    simplify the rest of the code.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=701482

 gio/Makefile.am               |    1 +
 gio/gcredentials.c            |  174 +++++++++++++++++-----------------------
 gio/gcredentialsprivate.h     |   51 ++++++++++++
 gio/gsocket.c                 |   36 ++++-----
 gio/gunixcredentialsmessage.c |  140 +++++++++++----------------------
 gio/tests/credentials.c       |   53 +++++++++----
 gio/tests/gdbus-peer.c        |   48 +++--------
 7 files changed, 238 insertions(+), 265 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 3661686..ba596e5 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -342,6 +342,7 @@ libgio_2_0_la_SOURCES =             \
        gconverterinputstream.c \
        gconverteroutputstream.c        \
        gcredentials.c          \
+       gcredentialsprivate.h   \
        gdatainputstream.c      \
        gdataoutputstream.c     \
        gdrive.c                \
diff --git a/gio/gcredentials.c b/gio/gcredentials.c
index ea59b47..8ac7a39 100644
--- a/gio/gcredentials.c
+++ b/gio/gcredentials.c
@@ -28,8 +28,10 @@
 #include <gobject/gvaluecollector.h>
 
 #include "gcredentials.h"
+#include "gcredentialsprivate.h"
 #include "gnetworking.h"
 #include "gioerror.h"
+#include "gioenumtypes.h"
 
 #include "glibintl.h"
 
@@ -77,16 +79,16 @@ struct _GCredentials
   /*< private >*/
   GObject parent_instance;
 
-#ifdef __linux__
+#if G_CREDENTIALS_USE_LINUX_UCRED
   struct ucred native;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   struct cmsgcred native;
-#elif defined(__OpenBSD__)
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   struct sockpeercred native;
 #else
-#ifdef __GNUC__
-#warning Please add GCredentials support for your OS
-#endif
+  #ifdef __GNUC__
+  #warning Please add GCredentials support for your OS
+  #endif
 #endif
 };
 
@@ -127,16 +129,16 @@ g_credentials_class_init (GCredentialsClass *klass)
 static void
 g_credentials_init (GCredentials *credentials)
 {
-#ifdef __linux__
+#if G_CREDENTIALS_USE_LINUX_UCRED
   credentials->native.pid = getpid ();
   credentials->native.uid = geteuid ();
   credentials->native.gid = getegid ();
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   memset (&credentials->native, 0, sizeof (struct cmsgcred));
   credentials->native.cmcred_pid  = getpid ();
   credentials->native.cmcred_euid = geteuid ();
   credentials->native.cmcred_gid  = getegid ();
-#elif defined(__OpenBSD__)
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   credentials->native.pid = getpid ();
   credentials->native.uid = geteuid ();
   credentials->native.gid = getegid ();
@@ -183,7 +185,7 @@ g_credentials_to_string (GCredentials *credentials)
   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL);
 
   ret = g_string_new ("GCredentials:");
-#ifdef __linux__
+#if G_CREDENTIALS_USE_LINUX_UCRED
   g_string_append (ret, "linux-ucred:");
   if (credentials->native.pid != -1)
     g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
@@ -193,7 +195,7 @@ g_credentials_to_string (GCredentials *credentials)
     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';
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   g_string_append (ret, "freebsd-cmsgcred:");
   if (credentials->native.cmcred_pid != -1)
     g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_pid);
@@ -201,7 +203,7 @@ g_credentials_to_string (GCredentials *credentials)
     g_string_append_printf (ret, "uid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_euid);
   if (credentials->native.cmcred_gid != -1)
     g_string_append_printf (ret, "gid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.cmcred_gid);
-#elif defined(__OpenBSD__)
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   g_string_append (ret, "openbsd-sockpeercred:");
   if (credentials->native.pid != -1)
     g_string_append_printf (ret, "pid=%" G_GINT64_FORMAT ",", (gint64) credentials->native.pid);
@@ -248,13 +250,13 @@ g_credentials_is_same_user (GCredentials  *credentials,
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   ret = FALSE;
-#ifdef __linux__
+#if G_CREDENTIALS_USE_LINUX_UCRED
   if (credentials->native.uid == other_credentials->native.uid)
     ret = TRUE;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
     ret = TRUE;
-#elif defined(__OpenBSD__)
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   if (credentials->native.uid == other_credentials->native.uid)
     ret = TRUE;
 #else
@@ -267,6 +269,42 @@ g_credentials_is_same_user (GCredentials  *credentials,
   return ret;
 }
 
+static gboolean
+credentials_native_type_check (GCredentialsType  requested_type,
+                               const char       *op)
+{
+  GEnumClass *enum_class;
+  GEnumValue *requested;
+#if G_CREDENTIALS_SUPPORTED
+  GEnumValue *supported;
+#endif
+
+#if G_CREDENTIALS_SUPPORTED
+  if (requested_type == G_CREDENTIALS_NATIVE_TYPE)
+    return TRUE;
+#endif
+
+  enum_class = g_type_class_ref (g_credentials_type_get_type ());
+  requested = g_enum_get_value (enum_class, requested_type);
+
+#if G_CREDENTIALS_SUPPORTED
+  supported = g_enum_get_value (enum_class, G_CREDENTIALS_NATIVE_TYPE);
+  g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s "
+             "but only %s is supported on this platform.",
+             op, op,
+             requested ? requested->value_name : "(unknown)",
+             supported->value_name);
+#else
+  g_warning ("g_credentials_%s_native: Trying to %s credentials of type %s "
+             "but there is no support for GCredentials on this platform.",
+             op, op,
+             requested ? requested->value_name : "(unknown)");
+#endif
+
+  g_type_class_unref (enum_class);
+  return FALSE;
+}
+
 /**
  * g_credentials_get_native: (skip)
  * @credentials: A #GCredentials.
@@ -290,51 +328,16 @@ gpointer
 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__
-  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;
-    }
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-  if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
-    {
-      g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
-                "G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED is supported.",
-                native_type);
-    }
-  else
-    {
-      ret = &credentials->native;
-    }
-#elif defined(__OpenBSD__)
-  if (native_type != G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED)
-    {
-      g_warning ("g_credentials_get_native: Trying to get credentials of type %d but only "
-                 "G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED is supported.",
-                 native_type);
-    }
-  else
-    {
-      ret = &credentials->native;
-    }
+  if (!credentials_native_type_check (native_type, "get"))
+    return NULL;
+
+#if G_CREDENTIALS_SUPPORTED
+  return &credentials->native;
 #else
-  g_warning ("g_credentials_get_native: Trying to get credentials but GLib has no support "
-             "for the native credentials type. Please add support.");
+  g_assert_not_reached ();
 #endif
-
-  return ret;
 }
 
 /**
@@ -357,42 +360,13 @@ g_credentials_set_native (GCredentials     *credentials,
                           GCredentialsType  native_type,
                           gpointer          native)
 {
-#ifdef __linux__
-  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));
-    }
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-  if (native_type != G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED)
-    {
-      g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
-                 "but only G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED is supported.",
-                 native_type);
-    }
-  else
-    {
-      memcpy (&credentials->native, native, sizeof (struct cmsgcred));
-    }
-#elif defined(__OpenBSD__)
-  if (native_type != G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED)
-    {
-      g_warning ("g_credentials_set_native: Trying to set credentials of type %d "
-                 "but only G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED is supported.",
-                 native_type);
-    }
-  else
-    {
-      memcpy (&credentials->native, native, sizeof (struct sockpeercred));
-    }
+  if (!credentials_native_type_check (native_type, "set"))
+    return;
+
+#if G_CREDENTIALS_SUPPORTED
+  memcpy (&credentials->native, native, sizeof (credentials->native));
 #else
-  g_warning ("g_credentials_set_native: Trying to set credentials but GLib has no support "
-             "for the native credentials type. Please add support.");
+  g_assert_not_reached ();
 #endif
 }
 
@@ -424,11 +398,11 @@ g_credentials_get_unix_user (GCredentials    *credentials,
   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
   g_return_val_if_fail (error == NULL || *error == NULL, -1);
 
-#ifdef __linux__
+#if G_CREDENTIALS_USE_LINUX_UCRED
   ret = credentials->native.uid;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   ret = credentials->native.cmcred_euid;
-#elif defined(__OpenBSD__)
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   ret = credentials->native.uid;
 #else
   ret = -1;
@@ -466,11 +440,11 @@ g_credentials_get_unix_pid (GCredentials    *credentials,
   g_return_val_if_fail (G_IS_CREDENTIALS (credentials), -1);
   g_return_val_if_fail (error == NULL || *error == NULL, -1);
 
-#ifdef __linux__
+#if G_CREDENTIALS_USE_LINUX_UCRED
   ret = credentials->native.pid;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   ret = credentials->native.cmcred_pid;
-#elif defined(__OpenBSD__)
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   ret = credentials->native.pid;
 #else
   ret = -1;
@@ -512,13 +486,13 @@ g_credentials_set_unix_user (GCredentials    *credentials,
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   ret = FALSE;
-#ifdef __linux__
+#if G_CREDENTIALS_USE_LINUX_UCRED
   credentials->native.uid = uid;
   ret = TRUE;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   credentials->native.cmcred_euid = uid;
   ret = TRUE;
-#elif defined(__OpenBSD__)
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
   credentials->native.uid = uid;
   ret = TRUE;
 #else
diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
new file mode 100644
index 0000000..3cb8fe0
--- /dev/null
+++ b/gio/gcredentialsprivate.h
@@ -0,0 +1,51 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_CREDENTIALS_PRIVATE_H__
+#define __G_CREDENTIALS_PRIVATE_H__
+
+#include "gio/gcredentials.h"
+#include "gio/gnetworking.h"
+
+#ifdef __linux__
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_LINUX_UCRED 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_LINUX_UCRED
+#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct ucred))
+#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
+#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_FREEBSD_CMSGCRED 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED
+#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct cmsgcred))
+#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
+
+#elif defined(__OpenBSD__)
+#define G_CREDENTIALS_SUPPORTED 1
+#define G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED 1
+#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED
+#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct sockpeercred))
+#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
+
+#endif
+
+#endif /* __G_CREDENTIALS_PRIVATE_H__ */
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 18e6137..5e66902 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -63,6 +63,7 @@
 #include "gsocketaddress.h"
 #include "gsocketcontrolmessage.h"
 #include "gcredentials.h"
+#include "gcredentialsprivate.h"
 #include "glibintl.h"
 
 /**
@@ -4447,21 +4448,23 @@ g_socket_get_credentials (GSocket   *socket,
 
   ret = NULL;
 
-#if defined(__linux__) || defined(__OpenBSD__)
+#if G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
   {
-    socklen_t optlen;
-#if defined(__linux__)
-    struct ucred native_creds;
-    optlen = sizeof (struct ucred);
-#elif defined(__OpenBSD__)
-    struct sockpeercred native_creds;
-    optlen = sizeof (struct sockpeercred);
-#endif
+    guint8 native_creds_buf[G_CREDENTIALS_NATIVE_SIZE];
+    socklen_t optlen = sizeof (native_creds_buf);
+
     if (getsockopt (socket->priv->fd,
                     SOL_SOCKET,
                     SO_PEERCRED,
-                    (void *)&native_creds,
-                    &optlen) != 0)
+                    native_creds_buf,
+                    &optlen) == 0)
+      {
+        ret = g_credentials_new ();
+        g_credentials_set_native (ret,
+                                  G_CREDENTIALS_NATIVE_TYPE,
+                                  native_creds_buf);
+      }
+    else
       {
         int errsv = get_socket_errno ();
         g_set_error (error,
@@ -4470,17 +4473,6 @@ g_socket_get_credentials (GSocket   *socket,
                      _("Unable to read socket credentials: %s"),
                      socket_strerror (errsv));
       }
-    else
-      {
-        ret = g_credentials_new ();
-        g_credentials_set_native (ret,
-#if defined(__linux__)
-                                  G_CREDENTIALS_TYPE_LINUX_UCRED,
-#elif defined(__OpenBSD__)
-                                  G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED,
-#endif
-                                  &native_creds);
-      }
   }
 #else
   g_set_error_literal (error,
diff --git a/gio/gunixcredentialsmessage.c b/gio/gunixcredentialsmessage.c
index 075a08d..25432a0 100644
--- a/gio/gunixcredentialsmessage.c
+++ b/gio/gunixcredentialsmessage.c
@@ -36,16 +36,6 @@
 #include "config.h"
 
 /* ---------------------------------------------------------------------------------------------------- */
-#ifdef __linux__
-#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
-#else
-/* TODO: please add support for your UNIX flavor */
-#define G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 0
-#endif
-
-/* ---------------------------------------------------------------------------------------------------- */
 
 #include <fcntl.h>
 #include <errno.h>
@@ -54,6 +44,7 @@
 
 #include "gunixcredentialsmessage.h"
 #include "gcredentials.h"
+#include "gcredentialsprivate.h"
 #include "gnetworking.h"
 
 #include "glibintl.h"
@@ -70,13 +61,12 @@ enum
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GUnixCredentialsMessage, g_unix_credentials_message, 
G_TYPE_SOCKET_CONTROL_MESSAGE)
+
 static gsize
 g_unix_credentials_message_get_size (GSocketControlMessage *message)
 {
-#ifdef __linux__
-  return sizeof (struct ucred);
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-  return sizeof (struct cmsgcred);
+#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
+  return G_CREDENTIALS_NATIVE_SIZE;
 #else
   return 0;
 #endif
@@ -85,9 +75,7 @@ g_unix_credentials_message_get_size (GSocketControlMessage *message)
 static int
 g_unix_credentials_message_get_level (GSocketControlMessage *message)
 {
-#ifdef __linux__
-  return SOL_SOCKET;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
   return SOL_SOCKET;
 #else
   return 0;
@@ -97,10 +85,12 @@ g_unix_credentials_message_get_level (GSocketControlMessage *message)
 static int
 g_unix_credentials_message_get_msg_type (GSocketControlMessage *message)
 {
-#ifdef __linux__
+#if G_CREDENTIALS_USE_LINUX_UCRED
   return SCM_CREDENTIALS;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   return SCM_CREDS;
+#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"
 #else
   return 0;
 #endif
@@ -112,91 +102,53 @@ g_unix_credentials_message_deserialize (gint     level,
                                         gsize    size,
                                         gpointer data)
 {
+#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
   GSocketControlMessage *message;
+  GCredentials *credentials;
 
-  message = NULL;
-
-#ifdef __linux__
-  {
-    GCredentials *credentials;
-    struct ucred *ucred;
-
-    if (level != SOL_SOCKET || type != SCM_CREDENTIALS)
-      goto out;
-
-    if (size != sizeof (struct ucred))
-      {
-        g_warning ("Expected a struct ucred (%" G_GSIZE_FORMAT " bytes) but "
-                   "got %" G_GSIZE_FORMAT " bytes of data",
-                   sizeof (struct ucred),
-                   size);
-        goto out;
-      }
-
-    ucred = data;
-
-    if (ucred->uid == (uid_t)-1 &&
-       ucred->gid == (gid_t)-1)
-      {
-       /* This happens if the remote side didn't pass the credentials */
-       goto out;
-      }
-
-    credentials = g_credentials_new ();
-    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:
-    ;
-  }
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-  {
-    GCredentials *credentials;
-    struct cmsgcred *cred;
-
-    if (level != SOL_SOCKET || type != SCM_CREDS)
-      {
-        goto out;
-      }
-    if (size < sizeof *cred)
-      {
-        g_warning ("Expected a struct cmsgcred (%" G_GSIZE_FORMAT " bytes) but "
-                   "got %" G_GSIZE_FORMAT " bytes of data",
-                   CMSG_LEN (sizeof *cred),
-                   size);
-        goto out;
-      }
-
-    cred = data;
-
-    credentials = g_credentials_new ();
-    g_credentials_set_native (credentials, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, cred);
-    message = g_unix_credentials_message_new_with_credentials (credentials);
-    g_object_unref (credentials);
- out:
-    ;
-  }
-#endif
+  if (level != SOL_SOCKET || type != g_unix_credentials_message_get_msg_type (NULL))
+    return NULL;
+
+  if (size != G_CREDENTIALS_NATIVE_SIZE)
+    {
+      g_warning ("Expected a credentials struct of %" G_GSIZE_FORMAT " bytes but "
+                 "got %" G_GSIZE_FORMAT " bytes of data",
+                 G_CREDENTIALS_NATIVE_SIZE, size);
+      return NULL;
+    }
+
+  credentials = g_credentials_new ();
+  g_credentials_set_native (credentials, G_CREDENTIALS_NATIVE_TYPE, data);
+
+  if (g_credentials_get_unix_user (credentials, NULL) == (uid_t) -1)
+    {
+      /* This happens on Linux if the remote side didn't pass the credentials */
+      g_object_unref (credentials);
+      return NULL;
+    }
+
+  message = g_unix_credentials_message_new_with_credentials (credentials);
+  g_object_unref (credentials);
 
   return message;
+
+#else /* !G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED */
+
+  return NULL;
+#endif
 }
 
 static void
 g_unix_credentials_message_serialize (GSocketControlMessage *_message,
                                       gpointer               data)
 {
+#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
   GUnixCredentialsMessage *message = G_UNIX_CREDENTIALS_MESSAGE (_message);
-#ifdef __linux__
-  memcpy (data,
-          g_credentials_get_native (message->priv->credentials,
-                                    G_CREDENTIALS_TYPE_LINUX_UCRED),
-          sizeof (struct ucred));
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+
   memcpy (data,
           g_credentials_get_native (message->priv->credentials,
-                                    G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED),
-          sizeof (struct cmsgcred));
-
+                                    G_CREDENTIALS_NATIVE_TYPE),
+          G_CREDENTIALS_NATIVE_SIZE);
 #endif
 }
 
@@ -324,7 +276,11 @@ g_unix_credentials_message_class_init (GUnixCredentialsMessageClass *class)
 gboolean
 g_unix_credentials_message_is_supported (void)
 {
-  return G_UNIX_CREDENTIALS_MESSAGE_SUPPORTED;
+#if G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
+  return TRUE;
+#else
+  return FALSE;
+#endif
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/gio/tests/credentials.c b/gio/tests/credentials.c
index 20cfcb9..53a42ec 100644
--- a/gio/tests/credentials.c
+++ b/gio/tests/credentials.c
@@ -23,24 +23,15 @@
 #include "config.h"
 
 #include <gio/gio.h>
-
-#ifdef G_OS_UNIX
-# include "gio/gnetworkingprivate.h"
-
-# if (defined(__linux__) || \
-  defined(__FreeBSD__) || \
-  defined(__FreeBSD_kernel__) || \
-  defined(__OpenBSD__))
-#   define SHOULD_HAVE_CREDENTIALS
-# endif
-#endif
+#include <gio/gcredentialsprivate.h>
 
 static void
 test_basic (void)
 {
   GCredentials *creds = g_credentials_new ();
   GCredentials *other = g_credentials_new ();
-#ifdef SHOULD_HAVE_CREDENTIALS
+  gpointer bad_native_creds;
+#if G_CREDENTIALS_SUPPORTED
   GError *error = NULL;
   gboolean set;
   pid_t not_me;
@@ -51,7 +42,7 @@ test_basic (void)
   g_assert (creds != NULL);
   g_assert (other != NULL);
 
-#ifdef SHOULD_HAVE_CREDENTIALS
+#if G_CREDENTIALS_SUPPORTED
   g_assert (g_credentials_is_same_user (creds, other, &error));
   g_assert_no_error (error);
 
@@ -83,7 +74,7 @@ test_basic (void)
   g_test_message ("%s", stringified);
   g_free (stringified);
 
-#if defined(__linux__)
+#if G_CREDENTIALS_USE_LINUX_UCRED
         {
           struct ucred *native = g_credentials_get_native (creds,
               G_CREDENTIALS_TYPE_LINUX_UCRED);
@@ -91,7 +82,7 @@ test_basic (void)
           g_assert_cmpuint (native->uid, ==, geteuid ());
           g_assert_cmpuint (native->pid, ==, getpid ());
         }
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
         {
           struct cmsgcred *native = g_credentials_get_native (creds,
               G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED);
@@ -99,7 +90,7 @@ test_basic (void)
           g_assert_cmpuint (native->cmcred_euid, ==, geteuid ());
           g_assert_cmpuint (native->cmcred_pid, ==, getpid ());
         }
-#elif defined(__OpenBSD__)
+#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
         {
           struct sockpeercred *native = g_credentials_get_native (creds,
               G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED);
@@ -107,8 +98,38 @@ test_basic (void)
           g_assert_cmpuint (native->uid, ==, geteuid ());
           g_assert_cmpuint (native->pid, ==, getpid ());
         }
+#else
+#error "G_CREDENTIALS_SUPPORTED is set but there is no test for this platform"
 #endif
 
+
+#if G_CREDENTIALS_USE_LINUX_UCRED
+  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
+                         "*g_credentials_get_native: Trying to get*"
+                         "G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED "
+                         "but only G_CREDENTIALS_TYPE_LINUX_UCRED*"
+                         "supported*");
+  bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED);
+  g_test_assert_expected_messages ();
+  g_assert_null (bad_native_creds);
+#else
+  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
+                         "*g_credentials_get_native: Trying to get*"
+                         "G_CREDENTIALS_TYPE_LINUX_UCRED "
+                         "but only G_CREDENTIALS_TYPE_*supported*");
+  bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_LINUX_UCRED);
+  g_test_assert_expected_messages ();
+  g_assert_null (bad_native_creds);
+#endif
+
+#else /* ! G_CREDENTIALS_SUPPORTED */
+
+  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
+                         "*g_credentials_get_native: Trying to get*"
+                         "credentials but*no support*");
+  bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_LINUX_UCRED);
+  g_test_assert_expected_messages ();
+  g_assert_null (bad_native_creds);
 #endif
 
   g_object_unref (creds);
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index dba892b..f0e93b4 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -38,19 +38,13 @@
 #include <gio/gnetworking.h>
 #include <gio/gunixsocketaddress.h>
 #include <gio/gunixfdlist.h>
+#include <gio/gcredentialsprivate.h>
 
 #ifdef G_OS_UNIX
 #include <gio/gunixconnection.h>
 #include <errno.h>
 #endif
 
-#if (defined(__linux__) || \
-  defined(__FreeBSD__) || \
-  defined(__FreeBSD_kernel__) || \
-  defined(__OpenBSD__))
-#define SHOULD_HAVE_CREDENTIALS_PASSING
-#endif
-
 #include "gdbus-tests.h"
 
 #include "gdbus-object-manager-example/gdbus-example-objectmanager-generated.h"
@@ -312,7 +306,7 @@ on_new_connection (GDBusServer *server,
 
   g_ptr_array_add (data->current_connections, g_object_ref (connection));
 
-#ifdef SHOULD_HAVE_CREDENTIALS_PASSING
+#if G_CREDENTIALS_SUPPORTED
     {
       GCredentials *credentials;
 
@@ -844,9 +838,8 @@ 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.
+  /* Check that g_socket_get_credentials() work - (though this really
+   * should be in socket.c)
    */
   {
     GSocket *socket;
@@ -855,30 +848,15 @@ test_peer (void)
     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);
-#elif defined (__OpenBSD__)
-    {
-      struct sockpeercred *native_creds;
-      g_assert_no_error (error);
-      g_assert (G_IS_CREDENTIALS (credentials));
-      native_creds = g_credentials_get_native (credentials, G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED);
-      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);
+
+#if G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
+    g_assert_no_error (error);
+    g_assert (G_IS_CREDENTIALS (credentials));
+
+    g_assert_cmpuint (g_credentials_get_unix_user (credentials, NULL), ==,
+                      getuid ());
+    g_assert_cmpuint (g_credentials_get_unix_pid (credentials, NULL), ==,
+                      getpid ());
 #else
     g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
     g_assert (credentials == NULL);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]