[polypaudio-commits] r596 - in /trunk/src: modules/ polyp/ polypcore/

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Fri Feb 24 07:12:44 PST 2006


Author: lennart
Date: Fri Feb 24 16:12:42 2006
New Revision: 596

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=596&root=polypaudio&view=rev
Log:
add support for authentication using SCM_CREDENTIALS

Modified:
    trunk/src/modules/module-tunnel.c
    trunk/src/polyp/context.c
    trunk/src/polyp/subscribe.c
    trunk/src/polypcore/iochannel.c
    trunk/src/polypcore/iochannel.h
    trunk/src/polypcore/pdispatch.c
    trunk/src/polypcore/pdispatch.h
    trunk/src/polypcore/protocol-native.c
    trunk/src/polypcore/pstream-util.c
    trunk/src/polypcore/pstream-util.h
    trunk/src/polypcore/pstream.c
    trunk/src/polypcore/pstream.h

Modified: trunk/src/modules/module-tunnel.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-tunnel.c?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/modules/module-tunnel.c (original)
+++ trunk/src/modules/module-tunnel.c Fri Feb 24 16:12:42 2006
@@ -431,11 +431,11 @@
 }
 
 
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const void*creds, void *userdata) {
     struct userdata *u = userdata;
     assert(p && packet && u);
 
-    if (pa_pdispatch_run(u->pdispatch, packet, u) < 0) {
+    if (pa_pdispatch_run(u->pdispatch, packet, creds, u) < 0) {
         pa_log(__FILE__": invalid packet");
         die(u);
     }

Modified: trunk/src/polyp/context.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polyp/context.c?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polyp/context.c (original)
+++ trunk/src/polyp/context.c Fri Feb 24 16:12:42 2006
@@ -267,7 +267,7 @@
     pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
 }
 
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const void *creds, void *userdata) {
     pa_context *c = userdata;
     
     assert(p);
@@ -276,7 +276,7 @@
 
     pa_context_ref(c);
     
-    if (pa_pdispatch_run(c->pdispatch, packet, c) < 0)
+    if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0)
         pa_context_fail(c, PA_ERR_PROTOCOL);
 
     pa_context_unref(c);
@@ -401,7 +401,7 @@
 
     t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag);
     pa_tagstruct_put_arbitrary(t, c->conf->cookie, sizeof(c->conf->cookie));
-    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pstream_send_tagstruct_with_creds(c->pstream, t, 1);
     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, setup_complete_callback, c);
 
     pa_context_set_state(c, PA_CONTEXT_AUTHORIZING);

Modified: trunk/src/polyp/subscribe.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polyp/subscribe.c?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polyp/subscribe.c (original)
+++ trunk/src/polyp/subscribe.c Fri Feb 24 16:12:42 2006
@@ -36,7 +36,7 @@
 void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_context *c = userdata;
     pa_subscription_event_type_t e;
-    uint32_t index;
+    uint32_t idx;
 
     assert(pd);
     assert(command == PA_COMMAND_SUBSCRIBE_EVENT);
@@ -46,14 +46,14 @@
     pa_context_ref(c);
 
     if (pa_tagstruct_getu32(t, &e) < 0 ||
-        pa_tagstruct_getu32(t, &index) < 0 ||
+        pa_tagstruct_getu32(t, &idx) < 0 ||
         !pa_tagstruct_eof(t)) {
         pa_context_fail(c, PA_ERR_PROTOCOL);
         goto finish;
     }
 
     if (c->subscribe_callback)
-        c->subscribe_callback(c, e, index, c->subscribe_userdata);
+        c->subscribe_callback(c, e, idx, c->subscribe_userdata);
 
 finish:
     pa_context_unref(c);

Modified: trunk/src/polypcore/iochannel.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/iochannel.c?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/iochannel.c (original)
+++ trunk/src/polypcore/iochannel.c Fri Feb 24 16:12:42 2006
@@ -27,12 +27,14 @@
 #include <assert.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include "winsock.h"
 
 #include <polypcore/util.h>
 #include <polypcore/socket-util.h>
 #include <polypcore/xmalloc.h>
+#include <polypcore/log.h>
 
 #include "iochannel.h"
 
@@ -242,6 +244,134 @@
     return r;
 }
 
+#ifdef SCM_CREDENTIALS
+
+int pa_iochannel_creds_supported(pa_iochannel *io) {
+    struct sockaddr_un sa;
+    socklen_t l;
+    
+    assert(io);
+    assert(io->ifd >= 0);
+    assert(io->ofd == io->ifd);
+
+    l = sizeof(sa);
+    
+    if (getsockname(io->ifd, (struct sockaddr*) &sa, &l) < 0)
+        return 0;
+
+    return sa.sun_family == AF_UNIX;
+}
+
+int pa_iochannel_creds_enable(pa_iochannel *io) {
+    int t = 1;
+
+    assert(io);
+    assert(io->ifd >= 0);
+    
+    if (setsockopt(io->ifd, SOL_SOCKET, SO_PASSCRED, &t, sizeof(t)) < 0) {
+        pa_log_error("setsockopt(SOL_SOCKET, SO_PASSCRED): %s", strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l) {
+    ssize_t r;
+    struct msghdr mh;
+    struct iovec iov;
+    uint8_t cmsg_data[CMSG_SPACE(sizeof(struct ucred))];
+    struct ucred *ucred;
+    struct cmsghdr *cmsg;
+    
+    assert(io);
+    assert(data);
+    assert(l);
+    assert(io->ofd >= 0);
+
+    memset(&iov, 0, sizeof(iov));
+    iov.iov_base = (void*) data;
+    iov.iov_len = l;
+
+    memset(cmsg_data, 0, sizeof(cmsg_data));
+    cmsg = (struct cmsghdr*)  cmsg_data;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_CREDENTIALS;
+
+    ucred = (struct ucred*) CMSG_DATA(cmsg);
+    ucred->pid = getpid();
+    ucred->uid = getuid();
+    ucred->gid = getgid();
+    
+    memset(&mh, 0, sizeof(mh));
+    mh.msg_name = NULL;
+    mh.msg_namelen = 0;
+    mh.msg_iov = &iov;
+    mh.msg_iovlen = 1;
+    mh.msg_control = cmsg_data;
+    mh.msg_controllen = sizeof(cmsg_data);
+    mh.msg_flags = 0;
+
+    if ((r = sendmsg(io->ofd, &mh, MSG_NOSIGNAL)) >= 0) {
+        io->writable = 0;
+        enable_mainloop_sources(io);
+    }
+
+    return r;
+}
+
+ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid) {
+    ssize_t r;
+    struct msghdr mh;
+    struct iovec iov;
+    uint8_t cmsg_data[CMSG_SPACE(sizeof(struct ucred))];
+    
+    assert(io);
+    assert(data);
+    assert(l);
+    assert(io->ifd >= 0);
+    assert(ucred);
+    assert(creds_valid);
+
+    memset(&iov, 0, sizeof(iov));
+    iov.iov_base = data;
+    iov.iov_len = l;
+
+    memset(cmsg_data, 0, sizeof(cmsg_data));
+
+    memset(&mh, 0, sizeof(mh));
+    mh.msg_name = NULL;
+    mh.msg_namelen = 0;
+    mh.msg_iov = &iov;
+    mh.msg_iovlen = 1;
+    mh.msg_control = cmsg_data;
+    mh.msg_controllen = sizeof(cmsg_data);
+    mh.msg_flags = 0;
+
+    if ((r = recvmsg(io->ifd, &mh, MSG_NOSIGNAL)) >= 0) {
+        struct cmsghdr *cmsg;
+
+        *creds_valid = 0;
+    
+        for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
+            
+            if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
+                assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)));
+                memcpy(ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
+                *creds_valid = 1;
+                break;
+            }
+        }
+
+        io->readable = 0;
+        enable_mainloop_sources(io);
+    }
+    
+    return r;
+}
+#endif
+
 void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t _callback, void *userdata) {
     assert(io);
     

Modified: trunk/src/polypcore/iochannel.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/iochannel.h?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/iochannel.h (original)
+++ trunk/src/polypcore/iochannel.h Fri Feb 24 16:12:42 2006
@@ -23,6 +23,9 @@
 ***/
 
 #include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
 #include <polyp/mainloop-api.h>
 
 /* A wrapper around UNIX file descriptors for attaching them to the a
@@ -48,6 +51,14 @@
 ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l);
 ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l);
 
+#ifdef SCM_CREDENTIALS
+int pa_iochannel_creds_supported(pa_iochannel *io);
+int pa_iochannel_creds_enable(pa_iochannel *io);
+
+ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l);
+ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid);
+#endif
+
 int pa_iochannel_is_readable(pa_iochannel*io);
 int pa_iochannel_is_writable(pa_iochannel*io);
 int pa_iochannel_is_hungup(pa_iochannel*io);

Modified: trunk/src/polypcore/pdispatch.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/pdispatch.c?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/pdispatch.c (original)
+++ trunk/src/polypcore/pdispatch.c Fri Feb 24 16:12:42 2006
@@ -109,6 +109,7 @@
     PA_LLIST_HEAD(struct reply_info, replies);
     pa_pdispatch_drain_callback drain_callback;
     void *drain_userdata;
+    const void *creds;
 };
 
 static void reply_info_free(struct reply_info *r) {
@@ -136,7 +137,8 @@
     PA_LLIST_HEAD_INIT(pa_reply_info, pd->replies);
     pd->drain_callback = NULL;
     pd->drain_userdata = NULL;
-
+    pd->creds = NULL;
+    
     return pd;
 }
 
@@ -171,7 +173,7 @@
     pa_pdispatch_unref(pd);
 }
 
-int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, void *userdata) {
+int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const void *creds, void *userdata) {
     uint32_t tag, command;
     pa_tagstruct *ts = NULL;
     int ret = -1;
@@ -188,17 +190,19 @@
     if (pa_tagstruct_getu32(ts, &command) < 0 ||
         pa_tagstruct_getu32(ts, &tag) < 0)
         goto finish;
-
+    
 #ifdef DEBUG_OPCODES
 {
     char t[256];
     char const *p;
     if (!(p = command_names[command]))
         snprintf((char*) (p = t), sizeof(t), "%u", command);
-        
+    
     pa_log(__FILE__": Recieved opcode <%s>", p);
 }
 #endif
+
+    pd->creds = creds;
 
     if (command == PA_COMMAND_ERROR || command == PA_COMMAND_REPLY) {
         struct reply_info *r;
@@ -222,6 +226,8 @@
     ret = 0;
         
 finish:
+    pd->creds = NULL;
+    
     if (ts)
         pa_tagstruct_free(ts);
 
@@ -295,3 +301,10 @@
     pd->ref++;
     return pd;
 }
+
+const void * pa_pdispatch_creds(pa_pdispatch *pd) {
+    assert(pd);
+    assert(pd->ref >= 1);
+    
+    return pd->creds;
+}

Modified: trunk/src/polypcore/pdispatch.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/pdispatch.h?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/pdispatch.h (original)
+++ trunk/src/polypcore/pdispatch.h Fri Feb 24 16:12:42 2006
@@ -30,21 +30,23 @@
 typedef struct pa_pdispatch pa_pdispatch;
 
 typedef void (*pa_pdispatch_cb_t)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+typedef void (*pa_pdispatch_drain_callback)(pa_pdispatch *pd, void *userdata);
 
 pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *m, const pa_pdispatch_cb_t*table, unsigned entries);
 void pa_pdispatch_unref(pa_pdispatch *pd);
 pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd);
 
-int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, void *userdata);
+int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, const void*creds, void *userdata);
 
 void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t callback, void *userdata);
 
 int pa_pdispatch_is_pending(pa_pdispatch *pd);
 
-typedef void (*pa_pdispatch_drain_callback)(pa_pdispatch *pd, void *userdata);
 void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, pa_pdispatch_drain_callback callback, void *userdata);
 
 /* Remove all reply slots with the give userdata parameter */
 void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata);
 
+const void * pa_pdispatch_creds(pa_pdispatch *pd);
+
 #endif

Modified: trunk/src/polypcore/protocol-native.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/protocol-native.c?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/protocol-native.c (original)
+++ trunk/src/polypcore/protocol-native.c Fri Feb 24 16:12:42 2006
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <assert.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include <polypcore/native-common.h>
 #include <polypcore/packet.h>
@@ -357,7 +358,7 @@
     pa_cvolume *volume,
     uint32_t syncid) {
     
-    struct playback_stream *s, *sync;
+    struct playback_stream *s, *ssync;
     pa_sink_input *sink_input;
     pa_memblock *silence;
     uint32_t idx;
@@ -366,17 +367,17 @@
     assert(c && sink && ss && name && maxlength);
 
     /* Find syncid group */
-    for (sync = pa_idxset_first(c->output_streams, &idx); sync; sync = pa_idxset_next(c->output_streams, &idx)) {
+    for (ssync = pa_idxset_first(c->output_streams, &idx); ssync; ssync = pa_idxset_next(c->output_streams, &idx)) {
         
-        if (sync->type != PLAYBACK_STREAM)
+        if (ssync->type != PLAYBACK_STREAM)
             continue;
 
-        if (sync->syncid == syncid)
+        if (ssync->syncid == syncid)
             break;
     }
 
     /* Synced streams must connect to the same sink */
-    if (sync && sync->sink_input->sink != sink)
+    if (ssync && ssync->sink_input->sink != sink)
         return NULL;
     
     if (!(sink_input = pa_sink_input_new(sink, __FILE__, name, ss, map, 0, -1)))
@@ -397,16 +398,16 @@
     s->sink_input->owner = c->protocol->module;
     s->sink_input->client = c->client;
 
-    if (sync) {
+    if (ssync) {
         /* Sync id found, now find head of list */
-        PA_LLIST_FIND_HEAD(struct playback_stream, sync, &sync);
+        PA_LLIST_FIND_HEAD(struct playback_stream, ssync, &ssync);
 
         /* Prepend ourselves */
-        PA_LLIST_PREPEND(struct playback_stream, sync, s);
+        PA_LLIST_PREPEND(struct playback_stream, ssync, s);
 
         /* Set our start index to the current read index of the other grozp member(s) */
-        assert(sync->next);
-        start_index = pa_memblockq_get_read_index(sync->next->memblockq);
+        assert(ssync->next);
+        start_index = pa_memblockq_get_read_index(ssync->next->memblockq);
     } else {
         /* This ia a new sync group */
         PA_LLIST_INIT(struct playback_stream, s);
@@ -871,8 +872,29 @@
     }
 
     if (!c->authorized) {
-        if (memcmp(c->protocol->auth_cookie, cookie, PA_NATIVE_COOKIE_LENGTH) != 0) {
-            pa_log(__FILE__": Denied access to client with invalid authorization key.");
+        int success = 0;
+        
+#ifdef SCM_CREDENTIALS
+        const struct ucred *ucred = pa_pdispatch_creds(pd);
+
+        if (ucred) {
+            if (ucred->uid == getuid()) 
+                success = 1;
+                
+            pa_log_info(__FILE__": Got credentials: pid=%lu uid=%lu gid=%lu auth=%i",
+                        (unsigned long) ucred->pid,
+                        (unsigned long) ucred->uid,
+                        (unsigned long) ucred->gid,
+                        success);
+
+        }
+#endif
+
+        if (memcmp(c->protocol->auth_cookie, cookie, PA_NATIVE_COOKIE_LENGTH) == 0)
+            success = 1;
+
+        if (!success) {
+            pa_log_warn(__FILE__": Denied access to client with invalid authorization data.");
             pa_pstream_send_error(c->pstream, tag, PA_ERR_ACCESS);
             return;
         }
@@ -1589,7 +1611,7 @@
     struct connection *c = userdata;
     uint32_t idx;
     int b;
-    struct playback_stream *s, *sync;
+    struct playback_stream *s, *ssync;
     assert(c && t);
 
     if (pa_tagstruct_getu32(t, &idx) < 0 ||
@@ -1609,14 +1631,14 @@
     pa_memblockq_prebuf_force(s->memblockq);
 
     /* Do the same for all other members in the sync group */
-    for (sync = s->prev; sync; sync = sync->prev) {
-        pa_sink_input_cork(sync->sink_input, b);
-        pa_memblockq_prebuf_force(sync->memblockq);
-    }
-
-    for (sync = s->next; sync; sync = sync->next) {
-        pa_sink_input_cork(sync->sink_input, b);
-        pa_memblockq_prebuf_force(sync->memblockq);
+    for (ssync = s->prev; ssync; ssync = ssync->prev) {
+        pa_sink_input_cork(ssync->sink_input, b);
+        pa_memblockq_prebuf_force(ssync->memblockq);
+    }
+
+    for (ssync = s->next; ssync; ssync = ssync->next) {
+        pa_sink_input_cork(ssync->sink_input, b);
+        pa_memblockq_prebuf_force(ssync->memblockq);
     }
     
     pa_pstream_send_simple_ack(c->pstream, tag);
@@ -1625,7 +1647,7 @@
 static void command_flush_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     struct connection *c = userdata;
     uint32_t idx;
-    struct playback_stream *s, *sync;
+    struct playback_stream *s, *ssync;
     assert(c && t);
 
     if (pa_tagstruct_getu32(t, &idx) < 0 ||
@@ -1644,25 +1666,25 @@
     s->underrun = 0;
     
     /* Do the same for all other members in the sync group */
-    for (sync = s->prev; sync; sync = sync->prev) {
-        pa_memblockq_flush(sync->memblockq);
-        sync->underrun = 0;
-    }
-
-    for (sync = s->next; sync; sync = sync->next) {
-        pa_memblockq_flush(sync->memblockq);
-        sync->underrun = 0;
+    for (ssync = s->prev; ssync; ssync = ssync->prev) {
+        pa_memblockq_flush(ssync->memblockq);
+        ssync->underrun = 0;
+    }
+
+    for (ssync = s->next; ssync; ssync = ssync->next) {
+        pa_memblockq_flush(ssync->memblockq);
+        ssync->underrun = 0;
     }
     
     pa_pstream_send_simple_ack(c->pstream, tag);
     pa_sink_notify(s->sink_input->sink);
     request_bytes(s);
     
-    for (sync = s->prev; sync; sync = sync->prev)
-        request_bytes(sync);
-
-    for (sync = s->next; sync; sync = sync->next)
-        request_bytes(sync);
+    for (ssync = s->prev; ssync; ssync = ssync->prev)
+        request_bytes(ssync);
+
+    for (ssync = s->next; ssync; ssync = ssync->next)
+        request_bytes(ssync);
 }
 
 static void command_trigger_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -2017,11 +2039,11 @@
 
 /*** pstream callbacks ***/
 
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const void *creds, void *userdata) {
     struct connection *c = userdata;
     assert(p && packet && packet->data && c);
 
-    if (pa_pdispatch_run(c->pdispatch, packet, c) < 0) {
+    if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0) {
         pa_log(__FILE__": invalid packet.");
         connection_free(c);
     }
@@ -2183,6 +2205,13 @@
     c->subscription = NULL;
 
     pa_idxset_put(p->connections, c, NULL);
+
+
+#ifdef SCM_CREDENTIALS
+    if (pa_iochannel_creds_supported(io))
+        pa_iochannel_creds_enable(io);
+    
+#endif
 }
 
 /*** module entry points ***/

Modified: trunk/src/polypcore/pstream-util.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/pstream-util.c?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/pstream-util.c (original)
+++ trunk/src/polypcore/pstream-util.c Fri Feb 24 16:12:42 2006
@@ -29,7 +29,7 @@
 
 #include "pstream-util.h"
 
-void pa_pstream_send_tagstruct(pa_pstream *p, pa_tagstruct *t) {
+void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, int creds) {
     size_t length;
     uint8_t *data;
     pa_packet *packet;
@@ -40,7 +40,7 @@
     assert(data && length);
     packet = pa_packet_new_dynamic(data, length);
     assert(packet);
-    pa_pstream_send_packet(p, packet);
+    pa_pstream_send_packet(p, packet, creds);
     pa_packet_unref(packet);
 }
 

Modified: trunk/src/polypcore/pstream-util.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/pstream-util.h?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/pstream-util.h (original)
+++ trunk/src/polypcore/pstream-util.h Fri Feb 24 16:12:42 2006
@@ -27,7 +27,9 @@
 #include <polypcore/tagstruct.h>
 
 /* The tagstruct is freed!*/
-void pa_pstream_send_tagstruct(pa_pstream *p, pa_tagstruct *t);
+void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, int creds);
+
+#define pa_pstream_send_tagstruct(p, t) pa_pstream_send_tagstruct_with_creds((p), (t), 0)
 
 void pa_pstream_send_error(pa_pstream *p, uint32_t tag, uint32_t error);
 void pa_pstream_send_simple_ack(pa_pstream *p, uint32_t tag);

Modified: trunk/src/polypcore/pstream.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/pstream.c?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/pstream.c (original)
+++ trunk/src/polypcore/pstream.c Fri Feb 24 16:12:42 2006
@@ -65,6 +65,9 @@
 
     /* packet info */
     pa_packet *packet;
+#ifdef SCM_CREDENTIALS
+    int with_creds;
+#endif
 };
 
 struct pa_pstream {
@@ -76,8 +79,6 @@
     pa_queue *send_queue;
 
     int dead;
-    void (*die_callback) (pa_pstream *p, void *userdata);
-    void *die_callback_userdata;
 
     struct {
         struct item_info* current;
@@ -94,16 +95,25 @@
         size_t index;
     } read;
 
-    void (*recieve_packet_callback) (pa_pstream *p, pa_packet *packet, void *userdata);
+    pa_pstream_packet_cb_t recieve_packet_callback;
     void *recieve_packet_callback_userdata;
 
-    void (*recieve_memblock_callback) (pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata);
+    pa_pstream_memblock_cb_t recieve_memblock_callback;
     void *recieve_memblock_callback_userdata;
 
-    void (*drain_callback)(pa_pstream *p, void *userdata);
-    void *drain_userdata;
+    pa_pstream_notify_cb_t drain_callback;
+    void *drain_callback_userdata;
+
+    pa_pstream_notify_cb_t die_callback;
+    void *die_callback_userdata;
 
     pa_memblock_stat *memblock_stat;
+
+#ifdef SCM_CREDENTIALS
+    int send_creds_now;
+    struct ucred ucred;
+    int creds_valid;
+#endif
 };
 
 static int do_write(pa_pstream *p);
@@ -170,8 +180,6 @@
     pa_iochannel_set_callback(io, io_callback, p);
 
     p->dead = 0;
-    p->die_callback = NULL;
-    p->die_callback_userdata = NULL;
 
     p->mainloop = m;
     p->defer_event = m->defer_new(m, defer_callback, p);
@@ -194,13 +202,20 @@
     p->recieve_memblock_callback_userdata = NULL;
 
     p->drain_callback = NULL;
-    p->drain_userdata = NULL;
+    p->drain_callback_userdata = NULL;
+
+    p->die_callback = NULL;
+    p->die_callback_userdata = NULL;
 
     p->memblock_stat = s;
 
     pa_iochannel_socket_set_rcvbuf(io, 1024*8); 
-    pa_iochannel_socket_set_sndbuf(io, 1024*8); 
-
+    pa_iochannel_socket_set_sndbuf(io, 1024*8);
+
+#ifdef SCM_CREDENTIALS
+    p->send_creds_now = 0;
+    p->creds_valid = 0;
+#endif
     return p;
 }
 
@@ -239,7 +254,7 @@
     pa_xfree(p);
 }
 
-void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet) {
+void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, int with_creds) {
     struct item_info *i;
     assert(p && packet && p->ref >= 1);
 
@@ -251,6 +266,9 @@
     i = pa_xnew(struct item_info, 1);
     i->type = PA_PSTREAM_ITEM_PACKET;
     i->packet = pa_packet_ref(packet);
+#ifdef SCM_CREDENTIALS
+    i->with_creds = with_creds;
+#endif
 
     pa_queue_push(p->send_queue, i);
     p->mainloop->defer_enable(p->defer_event, 1);
@@ -276,20 +294,6 @@
 
     pa_queue_push(p->send_queue, i);
     p->mainloop->defer_enable(p->defer_event, 1);
-}
-
-void pa_pstream_set_recieve_packet_callback(pa_pstream *p, void (*callback) (pa_pstream *p, pa_packet *packet, void *userdata), void *userdata) {
-    assert(p && callback);
-
-    p->recieve_packet_callback = callback;
-    p->recieve_packet_callback_userdata = userdata;
-}
-
-void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, void (*callback) (pa_pstream *p, uint32_t channel, int64_t delta, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata), void *userdata) {
-    assert(p && callback);
-
-    p->recieve_memblock_callback = callback;
-    p->recieve_memblock_callback_userdata = userdata;
 }
 
 static void prepare_next_write_item(pa_pstream *p) {
@@ -310,6 +314,11 @@
         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = 0;
         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = 0;
         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_SEEK] = 0;
+
+#ifdef SCM_CREDENTIALS
+        p->send_creds_now = 1;
+#endif
+        
     } else {
         assert(p->write.current->type == PA_PSTREAM_ITEM_MEMBLOCK && p->write.current->chunk.memblock);
         p->write.data = (uint8_t*) p->write.current->chunk.memblock->data + p->write.current->chunk.index;
@@ -318,6 +327,10 @@
         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = htonl((uint32_t) (((uint64_t) p->write.current->offset) >> 32));
         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = htonl((uint32_t) ((uint64_t) p->write.current->offset));
         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_SEEK] = htonl(p->write.current->seek_mode);
+
+#ifdef SCM_CREDENTIALS
+        p->send_creds_now = 1;
+#endif
     }
 }
 
@@ -343,6 +356,16 @@
         l = ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE);
     }
 
+#ifdef SCM_CREDENTIALS
+    if (p->send_creds_now) {
+
+        if ((r = pa_iochannel_write_with_creds(p->io, d, l)) < 0)
+            return -1;
+
+        p->send_creds_now = 0;
+    } else
+#endif
+
     if ((r = pa_iochannel_write(p->io, d, l)) < 0)
         return -1;
 
@@ -354,7 +377,7 @@
         p->write.current = NULL;
 
         if (p->drain_callback && !pa_pstream_is_pending(p))
-            p->drain_callback(p, p->drain_userdata);
+            p->drain_callback(p, p->drain_callback_userdata);
     }
 
     return 0;
@@ -375,8 +398,19 @@
         l = ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE);
     }
 
+#ifdef SCM_CREDENTIALS
+    {
+        int b;
+        
+        if ((r = pa_iochannel_read_with_creds(p->io, d, l, &p->ucred, &b)) <= 0)
+            return -1;
+
+        p->creds_valid = p->creds_valid || b;
+    }
+#else
     if ((r = pa_iochannel_read(p->io, d, l)) <= 0)
         return -1;
+#endif
     
     p->read.index += r;
 
@@ -453,23 +487,57 @@
                 assert(p->read.packet);
                 
                 if (p->recieve_packet_callback)
-                    p->recieve_packet_callback(p, p->read.packet, p->recieve_packet_callback_userdata);
+#ifdef SCM_CREDENTIALS                    
+                    p->recieve_packet_callback(p, p->read.packet, p->creds_valid ? &p->ucred : NULL, p->recieve_packet_callback_userdata);
+#else
+                    p->recieve_packet_callback(p, p->read.packet, NULL, p->recieve_packet_callback_userdata);
+#endif
 
                 pa_packet_unref(p->read.packet);
                 p->read.packet = NULL;
             }
 
             p->read.index = 0;
+#ifdef SCM_CREDENTIALS
+            p->creds_valid = 0;
+#endif
         }
     }
 
     return 0;   
 }
 
-void pa_pstream_set_die_callback(pa_pstream *p, void (*callback)(pa_pstream *p, void *userdata), void *userdata) {
-    assert(p && callback);
-    p->die_callback = callback;
+void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) {
+    assert(p);
+    assert(p->ref >= 1);
+
+    p->die_callback = cb;
     p->die_callback_userdata = userdata;
+}
+
+
+void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) {
+    assert(p);
+    assert(p->ref >= 1);
+
+    p->drain_callback = cb;
+    p->drain_callback_userdata = userdata;
+}
+
+void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata) {
+    assert(p);
+    assert(p->ref >= 1);
+
+    p->recieve_packet_callback = cb;
+    p->recieve_packet_callback_userdata = userdata;
+}
+
+void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata) {
+    assert(p);
+    assert(p->ref >= 1);
+
+    p->recieve_memblock_callback = cb;
+    p->recieve_memblock_callback_userdata = userdata;
 }
 
 int pa_pstream_is_pending(pa_pstream *p) {
@@ -479,14 +547,6 @@
         return 0;
 
     return p->write.current || !pa_queue_is_empty(p->send_queue);
-}
-
-void pa_pstream_set_drain_callback(pa_pstream *p, void (*cb)(pa_pstream *p, void *userdata), void *userdata) {
-    assert(p);
-    assert(p->ref >= 1);
-
-    p->drain_callback = cb;
-    p->drain_userdata = userdata;
 }
 
 void pa_pstream_unref(pa_pstream*p) {

Modified: trunk/src/polypcore/pstream.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/polypcore/pstream.h?rev=596&root=polypaudio&r1=595&r2=596&view=diff
==============================================================================
--- trunk/src/polypcore/pstream.h (original)
+++ trunk/src/polypcore/pstream.h Fri Feb 24 16:12:42 2006
@@ -33,18 +33,22 @@
 
 typedef struct pa_pstream pa_pstream;
 
+typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const void *creds, void *userdata);
+typedef void (*pa_pstream_memblock_cb_t)(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata);
+typedef void (*pa_pstream_notify_cb_t)(pa_pstream *p, void *userdata);
+
 pa_pstream* pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_memblock_stat *s);
 void pa_pstream_unref(pa_pstream*p);
 pa_pstream* pa_pstream_ref(pa_pstream*p);
 
-void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet);
+void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, int with_creds);
 void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk);
 
-void pa_pstream_set_recieve_packet_callback(pa_pstream *p, void (*callback) (pa_pstream *p, pa_packet *packet, void *userdata), void *userdata);
-void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, void (*callback) (pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata), void *userdata);
-void pa_pstream_set_drain_callback(pa_pstream *p, void (*cb)(pa_pstream *p, void *userdata), void *userdata);
+void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata);
+void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata);
+void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata);
 
-void pa_pstream_set_die_callback(pa_pstream *p, void (*callback)(pa_pstream *p, void *userdata), void *userdata);
+void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata);
 
 int pa_pstream_is_pending(pa_pstream *p);
 




More information about the pulseaudio-commits mailing list