Blob Blame History Raw
From ea28c5586af179bdc968a420a3d5e7ba42d00029 Mon Sep 17 00:00:00 2001
From: Wim Taymans <wtaymans@redhat.com>
Date: Fri, 15 Jul 2016 12:34:31 +0200
Subject: [PATCH 04/18] creds: add pid to pa_creds and use store it in
 pa_client

Add the pid to the credentials ancillary data and store it in the
pa_client object when valid.
Add a new hook to be notified when a pa_client it authenticated
---
 src/modules/module-tunnel.c     |  1 +
 src/pulse/context.c             |  1 +
 src/pulsecore/client.h          |  4 ++++
 src/pulsecore/core.h            |  1 +
 src/pulsecore/creds.h           |  1 +
 src/pulsecore/iochannel.c       |  4 +++-
 src/pulsecore/protocol-native.c | 25 +++++++++++++++----------
 7 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index e08816b..d7114ee 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -1857,6 +1857,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
 
     ucred.uid = getuid();
     ucred.gid = getgid();
+    ucred.pid = getpid();
 
     pa_pstream_send_tagstruct_with_creds(u->pstream, t, &ucred);
 }
diff --git a/src/pulse/context.c b/src/pulse/context.c
index c39cbe7..445973e 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -642,6 +642,7 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
 
     ucred.uid = getuid();
     ucred.gid = getgid();
+    ucred.pid = getpid();
 
     pa_pstream_send_tagstruct_with_creds(c->pstream, t, &ucred);
 }
diff --git a/src/pulsecore/client.h b/src/pulsecore/client.h
index eb8173d..e34fb1e 100644
--- a/src/pulsecore/client.h
+++ b/src/pulsecore/client.h
@@ -26,6 +26,7 @@
 #include <pulse/proplist.h>
 #include <pulsecore/core.h>
 #include <pulsecore/module.h>
+#include <pulsecore/creds.h>
 
 /* Every connection to the server should have a pa_client
  * attached. That way the user may generate a listing of all connected
@@ -39,6 +40,9 @@ struct pa_client {
     pa_module *module;
     char *driver;
 
+    pa_creds creds;
+    bool creds_valid;
+
     pa_idxset *sink_inputs;
     pa_idxset *source_outputs;
 
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 802111b..8418289 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -114,6 +114,7 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT,
     PA_CORE_HOOK_CLIENT_NEW,
     PA_CORE_HOOK_CLIENT_PUT,
+    PA_CORE_HOOK_CLIENT_AUTH,
     PA_CORE_HOOK_CLIENT_UNLINK,
     PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED,
     PA_CORE_HOOK_CLIENT_SEND_EVENT,
diff --git a/src/pulsecore/creds.h b/src/pulsecore/creds.h
index 9fdbb4f..f489b0d 100644
--- a/src/pulsecore/creds.h
+++ b/src/pulsecore/creds.h
@@ -41,6 +41,7 @@ typedef struct pa_cmsg_ancil_data pa_cmsg_ancil_data;
 struct pa_creds {
     gid_t gid;
     uid_t uid;
+    uid_t pid;
 };
 
 /* Struct for handling ancillary data, i e, extra data that can be sent together with a message
diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c
index 8ace297..32fe0f2 100644
--- a/src/pulsecore/iochannel.c
+++ b/src/pulsecore/iochannel.c
@@ -323,13 +323,14 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l
 
     u = (struct ucred*) CMSG_DATA(&cmsg.hdr);
 
-    u->pid = getpid();
     if (ucred) {
         u->uid = ucred->uid;
         u->gid = ucred->gid;
+        u->pid = ucred->pid;
     } else {
         u->uid = getuid();
         u->gid = getgid();
+        u->pid = getpid();
     }
 
     pa_zero(mh);
@@ -439,6 +440,7 @@ ssize_t pa_iochannel_read_with_ancil_data(pa_iochannel*io, void*data, size_t l,
 
                 ancil_data->creds.gid = u.gid;
                 ancil_data->creds.uid = u.uid;
+                ancil_data->creds.pid = u.pid;
                 ancil_data->creds_valid = true;
             }
             else if (cmh->cmsg_type == SCM_RIGHTS) {
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 13f4f62..8f07b2d 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -2541,6 +2541,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
     pa_tagstruct *reply;
     pa_mem_type_t shm_type;
     bool shm_on_remote = false, do_shm;
+    const pa_creds *creds = NULL;
 
     pa_native_connection_assert_ref(c);
     pa_assert(t);
@@ -2578,13 +2579,19 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
 
     pa_proplist_setf(c->client->proplist, "native-protocol.version", "%u", c->version);
 
+#ifdef HAVE_CREDS
+    creds = pa_pdispatch_creds(pd);
+#endif
+
+    if (creds) {
+        c->client->creds = *creds;
+        c->client->creds_valid = true;
+    }
+
     if (!c->authorized) {
         bool success = false;
 
-#ifdef HAVE_CREDS
-        const pa_creds *creds;
-
-        if ((creds = pa_pdispatch_creds(pd))) {
+        if (creds) {
             if (creds->uid == getuid())
                 success = true;
             else if (c->options->auth_group) {
@@ -2609,7 +2616,6 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
                         (unsigned long) creds->gid,
                         (int) success);
         }
-#endif
 
         if (!success && c->options->auth_cookie) {
             const uint8_t *ac;
@@ -2643,17 +2649,13 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
         if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
             do_shm = false;
 
-#ifdef HAVE_CREDS
     if (do_shm) {
         /* Only enable SHM if both sides are owned by the same
          * user. This is a security measure because otherwise data
          * private to the user might leak. */
-
-        const pa_creds *creds;
-        if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
+        if (!creds || getuid() != creds->uid)
             do_shm = false;
     }
-#endif
 
     pa_log_debug("Negotiated SHM: %s", pa_yes_no(do_shm));
     pa_pstream_enable_shm(c->pstream, do_shm);
@@ -2691,6 +2693,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
 
     ucred.uid = getuid();
     ucred.gid = getgid();
+    ucred.pid = getpid();
 
     pa_pstream_send_tagstruct_with_creds(c->pstream, reply, &ucred);
 }
@@ -2711,6 +2714,8 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
     }
 
     setup_srbchannel(c, shm_type);
+
+    pa_hook_fire(&c->protocol->core->hooks[PA_CORE_HOOK_CLIENT_AUTH], c->client);
 }
 
 static void command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
-- 
2.9.3