[glib/nacho/creditals-local-peerpid-macos: 188/188] credentials: support the local peerpid on macos




commit 1848905a99fe80ce828f4ffe62b303b2f7a81e97
Author: Ignacio Casal Quinteiro <qignacio amazon com>
Date:   Wed Nov 24 11:15:05 2021 +0100

    credentials: support the local peerpid on macos
    
    xucred does not provide the peer pid id, but this can be fetched
    from the socket LOCAL_PEERPID option. Note that we only support
    it when creating the credentials from a local socket, if
    the credential comes from a message over a socket the peer
    pid id will not be set and -1 will be returned when trying
    to get the pid for the credential.

 gio/gcredentials.c        | 34 +++++++++++++++++++++++++++-------
 gio/gcredentialsprivate.h |  3 +++
 gio/gsocket.c             | 10 ++++++++++
 3 files changed, 40 insertions(+), 7 deletions(-)
---
diff --git a/gio/gcredentials.c b/gio/gcredentials.c
index ebbc2cc5b..71d47b0f1 100644
--- a/gio/gcredentials.c
+++ b/gio/gcredentials.c
@@ -91,6 +91,7 @@ struct _GCredentials
   struct ucred native;
 #elif G_CREDENTIALS_USE_APPLE_XUCRED
   struct xucred native;
+  pid_t pid;
 #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   struct cmsgcred native;
 #elif G_CREDENTIALS_USE_NETBSD_UNPCBID
@@ -170,6 +171,8 @@ g_credentials_init (GCredentials *credentials)
    * For now we fill it with -1 (meaning "no data"). */
   for (i = 1; i < NGROUPS; i++)
     credentials->native.cr_groups[i] = -1;
+
+  credentials->pid = -1;
 #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
   memset (&credentials->native, 0, sizeof (struct cmsgcred));
   credentials->native.cmcred_pid  = getpid ();
@@ -569,8 +572,7 @@ g_credentials_get_unix_user (GCredentials    *credentials,
  *
  * This operation can fail if #GCredentials is not supported on the
  * OS or if the native credentials type does not contain information
- * about the UNIX process ID (for example this is the case for
- * %G_CREDENTIALS_TYPE_APPLE_XUCRED).
+ * about the UNIX process ID.
  *
  * Returns: The UNIX process ID, or `-1` if @error is set.
  *
@@ -599,12 +601,18 @@ g_credentials_get_unix_pid (GCredentials    *credentials,
 #elif G_CREDENTIALS_USE_SOLARIS_UCRED
   ret = ucred_getpid (credentials->native);
 #else
-  /* this case includes G_CREDENTIALS_USE_APPLE_XUCRED */
+
+#if G_CREDENTIALS_USE_APPLE_XUCRED
+  ret = credentials->pid;
+#else
   ret = -1;
-  g_set_error_literal (error,
-                       G_IO_ERROR,
-                       G_IO_ERROR_NOT_SUPPORTED,
-                       _("GCredentials does not contain a process ID on this OS"));
+#endif
+
+  if (ret == -1)
+    g_set_error_literal (error,
+                         G_IO_ERROR,
+                         G_IO_ERROR_NOT_SUPPORTED,
+                         _("GCredentials does not contain a process ID on this OS"));
 #endif
 
   return ret;
@@ -671,4 +679,16 @@ g_credentials_set_unix_user (GCredentials    *credentials,
   return ret;
 }
 
+#ifdef __APPLE__
+void
+_g_credentials_set_local_peerid (GCredentials *credentials,
+                                 pid_t         pid)
+{
+  g_return_if_fail (G_IS_CREDENTIALS (credentials));
+  g_return_if_fail (pid >= 0);
+
+  credentials->pid = pid;
+}
+#endif /* __APPLE__ */
+
 #endif /* G_OS_UNIX */
diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
index 13d3bf327..eff1e9701 100644
--- a/gio/gcredentialsprivate.h
+++ b/gio/gcredentialsprivate.h
@@ -168,6 +168,9 @@
 #define G_CREDENTIALS_SPOOFING_SUPPORTED 1
 #define G_CREDENTIALS_HAS_PID 0
 
+void _g_credentials_set_local_peerid (GCredentials *credentials,
+                                      pid_t         pid);
+
 #endif
 
 #endif /* __G_CREDENTIALS_PRIVATE_H__ */
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 2569b76f0..d15a18101 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -6055,10 +6055,20 @@ g_socket_get_credentials (GSocket   *socket,
       {
         if (cred.cr_version == XUCRED_VERSION)
           {
+            pid_t pid;
+            socklen_t optlen = sizeof (pid);
+
             ret = g_credentials_new ();
             g_credentials_set_native (ret,
                                       G_CREDENTIALS_NATIVE_TYPE,
                                       &cred);
+
+            if (getsockopt (socket->priv->fd,
+                            SOL_LOCAL,
+                            LOCAL_PEERPID,
+                            &pid,
+                            &optlen) == 0)
+              _g_credentials_set_local_peerid (ret, pid);
           }
         else
           {


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