diff --git a/0001-tagstruct-add-copy-method.patch b/0001-tagstruct-add-copy-method.patch deleted file mode 100644 index 3b3da0b..0000000 --- a/0001-tagstruct-add-copy-method.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 12a76717da7950497ea94bad0ec449c43325ef0a Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Tue, 7 Apr 2015 16:42:31 +0200 -Subject: [PATCH 01/18] tagstruct: add copy method - -Add a method to copy a tagstruct. This will also reset the read pointer -back to the beginning. ---- - src/pulsecore/tagstruct.c | 13 +++++++++++++ - src/pulsecore/tagstruct.h | 2 ++ - 2 files changed, 15 insertions(+) - -diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c -index 8a29957..c29e49b 100644 ---- a/src/pulsecore/tagstruct.c -+++ b/src/pulsecore/tagstruct.c -@@ -97,6 +97,19 @@ void pa_tagstruct_free(pa_tagstruct*t) { - pa_xfree(t); - } - -+pa_tagstruct *pa_tagstruct_copy(pa_tagstruct*t) { -+ pa_tagstruct*tc; -+ -+ if (!(tc = pa_flist_pop(PA_STATIC_FLIST_GET(tagstructs)))) -+ tc = pa_xnew(pa_tagstruct, 1); -+ tc->data = pa_xmemdup(t->data, t->length); -+ tc->allocated = t->length; -+ tc->rindex = 0; -+ tc->type = PA_TAGSTRUCT_DYNAMIC; -+ -+ return tc; -+} -+ - static inline void extend(pa_tagstruct*t, size_t l) { - pa_assert(t); - pa_assert(t->type != PA_TAGSTRUCT_FIXED); -diff --git a/src/pulsecore/tagstruct.h b/src/pulsecore/tagstruct.h -index 348c65d..e648d75 100644 ---- a/src/pulsecore/tagstruct.h -+++ b/src/pulsecore/tagstruct.h -@@ -64,6 +64,8 @@ pa_tagstruct *pa_tagstruct_new(void); - pa_tagstruct *pa_tagstruct_new_fixed(const uint8_t* data, size_t length); - void pa_tagstruct_free(pa_tagstruct*t); - -+pa_tagstruct *pa_tagstruct_copy(pa_tagstruct*t); -+ - int pa_tagstruct_eof(pa_tagstruct*t); - const uint8_t* pa_tagstruct_data(pa_tagstruct*t, size_t *l); - --- -2.9.3 - diff --git a/0002-tagstruct-don-t-forget-to-copy-the-length.patch b/0002-tagstruct-don-t-forget-to-copy-the-length.patch deleted file mode 100644 index 95d76d3..0000000 --- a/0002-tagstruct-don-t-forget-to-copy-the-length.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 8f43f8ceae382fafcdf59533a5f3776b41c174cd Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Thu, 14 Jul 2016 17:35:54 +0200 -Subject: [PATCH 02/18] tagstruct: don't forget to copy the length - ---- - src/pulsecore/tagstruct.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c -index c29e49b..66ff8df 100644 ---- a/src/pulsecore/tagstruct.c -+++ b/src/pulsecore/tagstruct.c -@@ -104,6 +104,7 @@ pa_tagstruct *pa_tagstruct_copy(pa_tagstruct*t) { - tc = pa_xnew(pa_tagstruct, 1); - tc->data = pa_xmemdup(t->data, t->length); - tc->allocated = t->length; -+ tc->length = t->length; - tc->rindex = 0; - tc->type = PA_TAGSTRUCT_DYNAMIC; - --- -2.9.3 - diff --git a/0003-subscribe-fix-typo.patch b/0003-subscribe-fix-typo.patch deleted file mode 100644 index 0f4d441..0000000 --- a/0003-subscribe-fix-typo.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 4701b6b12e0c950bf96f2cc1db97688894e5fe15 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Tue, 7 Apr 2015 16:44:45 +0200 -Subject: [PATCH 03/18] subscribe: fix typo - ---- - src/pulsecore/core-subscribe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/pulsecore/core-subscribe.c b/src/pulsecore/core-subscribe.c -index 61c779b..5a88b7e 100644 ---- a/src/pulsecore/core-subscribe.c -+++ b/src/pulsecore/core-subscribe.c -@@ -206,7 +206,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i - pa_subscription_event *e; - pa_assert(c); - -- /* No need for queuing subscriptions of no one is listening */ -+ /* No need for queuing subscriptions if no one is listening */ - if (!c->subscriptions) - return; - --- -2.9.3 - diff --git a/0004-creds-add-pid-to-pa_creds-and-use-store-it-in-pa_cli.patch b/0004-creds-add-pid-to-pa_creds-and-use-store-it-in-pa_cli.patch deleted file mode 100644 index f740444..0000000 --- a/0004-creds-add-pid-to-pa_creds-and-use-store-it-in-pa_cli.patch +++ /dev/null @@ -1,200 +0,0 @@ -From ea28c5586af179bdc968a420a3d5e7ba42d00029 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -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 - #include - #include -+#include - - /* 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 - diff --git a/0005-access-Add-access-control-hooks.patch b/0005-access-Add-access-control-hooks.patch deleted file mode 100644 index 436f653..0000000 --- a/0005-access-Add-access-control-hooks.patch +++ /dev/null @@ -1,184 +0,0 @@ -From e158102a2e40e702af97e451c6445b6d851f88f3 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Tue, 7 Apr 2015 16:50:26 +0200 -Subject: [PATCH 05/18] access: Add access control hooks - -Add hooks to core to check if certain operations are allowed. ---- - src/Makefile.am | 1 + - src/pulsecore/access.h | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ - src/pulsecore/core.c | 5 +++ - src/pulsecore/core.h | 3 ++ - 4 files changed, 114 insertions(+) - create mode 100644 src/pulsecore/access.h - -diff --git a/src/Makefile.am b/src/Makefile.am -index 498a386..13682c5 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -948,6 +948,7 @@ libpulsecore_@PA_MAJORMINOR@_la_SOURCES = \ - pulsecore/filter/lfe-filter.c pulsecore/filter/lfe-filter.h \ - pulsecore/filter/biquad.c pulsecore/filter/biquad.h \ - pulsecore/filter/crossover.c pulsecore/filter/crossover.h \ -+ pulsecore/access.h \ - pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h \ - pulsecore/asyncq.c pulsecore/asyncq.h \ - pulsecore/auth-cookie.c pulsecore/auth-cookie.h \ -diff --git a/src/pulsecore/access.h b/src/pulsecore/access.h -new file mode 100644 -index 0000000..534f66c ---- /dev/null -+++ b/src/pulsecore/access.h -@@ -0,0 +1,105 @@ -+#ifndef fooaccesshfoo -+#define fooaccesshfoo -+ -+/*** -+ This file is part of PulseAudio. -+ -+ Copyright 2004-2006 Lennart Poettering -+ 2015 Wim Taymans -+ -+ PulseAudio 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.1 of the -+ License, or (at your option) any later version. -+ -+ PulseAudio 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 PulseAudio; if not, see . -+***/ -+ -+#include -+ -+#include -+ -+typedef enum pa_access_hook { -+ PA_ACCESS_HOOK_NONE = 0, -+ /* context */ -+ PA_ACCESS_HOOK_VIEW_SERVER, -+ PA_ACCESS_HOOK_EXIT_DAEMON, -+ PA_ACCESS_HOOK_SET_DEFAULT_SINK, -+ PA_ACCESS_HOOK_SET_DEFAULT_SOURCE, -+ PA_ACCESS_HOOK_STAT, -+ -+ /* introspection */ -+ PA_ACCESS_HOOK_VIEW_SINK, -+ PA_ACCESS_HOOK_SET_SINK_VOLUME, -+ PA_ACCESS_HOOK_SUSPEND_SINK, -+ PA_ACCESS_HOOK_SET_SINK_PORT, -+ PA_ACCESS_HOOK_SET_SINK_PORT_LATENCY_OFFSET, -+ PA_ACCESS_HOOK_ENTER_PASSTHROUGH_SINK, -+ PA_ACCESS_HOOK_LEAVE_PASSTHROUGH_SINK, -+ -+ PA_ACCESS_HOOK_VIEW_SOURCE, -+ PA_ACCESS_HOOK_SET_SOURCE_VOLUME, -+ PA_ACCESS_HOOK_SUSPEND_SOURCE, -+ PA_ACCESS_HOOK_SET_SOURCE_PORT, -+ PA_ACCESS_HOOK_SET_SOURCE_PORT_LATENCY_OFFSET, -+ PA_ACCESS_HOOK_ENTER_PASSTHROUGH_SOURCE, -+ PA_ACCESS_HOOK_LEAVE_PASSTHROUGH_SOURCE, -+ -+ PA_ACCESS_HOOK_VIEW_MODULE, -+ PA_ACCESS_HOOK_LOAD_MODULE, -+ PA_ACCESS_HOOK_UNLOAD_MODULE, -+ -+ PA_ACCESS_HOOK_VIEW_CLIENT, -+ PA_ACCESS_HOOK_KILL_CLIENT, -+ -+ PA_ACCESS_HOOK_VIEW_CARD, -+ PA_ACCESS_HOOK_SET_CARD_PROFILE, -+ PA_ACCESS_HOOK_SUSPEND_CARD, -+ -+ PA_ACCESS_HOOK_VIEW_SINK_INPUT, -+ PA_ACCESS_HOOK_CREATE_SINK_INPUT, -+ PA_ACCESS_HOOK_MOVE_SINK_INPUT, -+ PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME, -+ PA_ACCESS_HOOK_KILL_SINK_INPUT, -+ -+ PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT, -+ PA_ACCESS_HOOK_CREATE_SOURCE_OUTPUT, -+ PA_ACCESS_HOOK_MOVE_SOURCE_OUTPUT, -+ PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME, -+ PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT, -+ -+ /* sample cache */ -+ PA_ACCESS_HOOK_VIEW_SAMPLE, -+ PA_ACCESS_HOOK_ADD_SAMPLE, -+ PA_ACCESS_HOOK_REMOVE_SAMPLE, -+ PA_ACCESS_HOOK_PLAY_SAMPLE, -+ PA_ACCESS_HOOK_PLAY_FILE, -+ -+ /* async */ -+ PA_ACCESS_HOOK_CONNECT_UPLOAD, -+ PA_ACCESS_HOOK_CONNECT_PLAYBACK, -+ PA_ACCESS_HOOK_CONNECT_RECORD, -+ -+ PA_ACCESS_HOOK_FILTER_SUBSCRIBE_EVENT, -+ -+ PA_ACCESS_HOOK_MAX -+} pa_access_hook_t; -+ -+typedef struct pa_access_data pa_access_data; -+ -+struct pa_access_data { -+ pa_access_hook_t hook; -+ uint32_t client_index; -+ uint32_t object_index; -+ pa_subscription_event_type_t event; -+ const char *name; -+ void (*complete_cb) (pa_access_data *data, bool res); -+}; -+ -+#endif -diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c -index 2a96dfa..e5d6879 100644 ---- a/src/pulsecore/core.c -+++ b/src/pulsecore/core.c -@@ -150,6 +150,9 @@ pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t - for (j = 0; j < PA_CORE_HOOK_MAX; j++) - pa_hook_init(&c->hooks[j], c); - -+ for (j = 0; j < PA_ACCESS_HOOK_MAX; j++) -+ pa_hook_init(&c->access[j], c); -+ - pa_random(&c->cookie, sizeof(c->cookie)); - - #ifdef SIGPIPE -@@ -219,6 +222,8 @@ static void core_free(pa_object *o) { - - for (j = 0; j < PA_CORE_HOOK_MAX; j++) - pa_hook_done(&c->hooks[j]); -+ for (j = 0; j < PA_ACCESS_HOOK_MAX; j++) -+ pa_hook_done(&c->access[j]); - - pa_xfree(c); - } -diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h -index 8418289..152a53f 100644 ---- a/src/pulsecore/core.h -+++ b/src/pulsecore/core.h -@@ -49,6 +49,7 @@ typedef enum pa_suspend_cause { - #include - #include - #include -+#include - - typedef enum pa_server_type { - PA_SERVER_TYPE_UNSET, -@@ -212,6 +213,8 @@ struct pa_core { - - /* hooks */ - pa_hook hooks[PA_CORE_HOOK_MAX]; -+ /* access hooks */ -+ pa_hook access[PA_ACCESS_HOOK_MAX]; - }; - - PA_DECLARE_PUBLIC_CLASS(pa_core); --- -2.9.3 - diff --git a/0006-module-access-add-example-access-module.patch b/0006-module-access-add-example-access-module.patch deleted file mode 100644 index 6e83cfb..0000000 --- a/0006-module-access-add-example-access-module.patch +++ /dev/null @@ -1,539 +0,0 @@ -From 1eec5a0d01a657536cf8afb14d295d0f050ddd1d Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Tue, 7 Apr 2015 17:01:58 +0200 -Subject: [PATCH 06/18] module-access: add example access module - -Add an example access module that only allows access to the objects -created by the owner client. - -The code is structured in such a way that multiple profiles can be -made and that a profile can be activated based on the properties of -a client. - -Events need special handling, we don't want to send events to clients -about objects they are not allowed to see. We need to be careful because -we can't inspect the owner of an object anymore in a _REMOVE event for -that object. We fix this by keeping a list of all the objects for which -we were allowed to notify a CHANGE or NEW event. We then only send -REMOVE events to objects from this list. ---- - src/Makefile.am | 7 + - src/modules/module-access.c | 474 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 481 insertions(+) - create mode 100644 src/modules/module-access.c - -diff --git a/src/Makefile.am b/src/Makefile.am -index 13682c5..7c66064 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -1178,6 +1178,7 @@ modlibexec_LTLIBRARIES += \ - endif - - modlibexec_LTLIBRARIES += \ -+ module-access.la \ - module-cli.la \ - module-cli-protocol-tcp.la \ - module-simple-protocol-tcp.la \ -@@ -1470,6 +1471,7 @@ endif - - # These are generated by an M4 script - SYMDEF_FILES = \ -+ module-access-symdef.h \ - module-cli-symdef.h \ - module-cli-protocol-tcp-symdef.h \ - module-cli-protocol-unix-symdef.h \ -@@ -1592,6 +1594,11 @@ module_simple_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_SIMPLE - module_simple_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS) - module_simple_protocol_unix_la_LIBADD = $(MODULE_LIBADD) libprotocol-simple.la - -+# Access control -+module_access_la_SOURCES = modules/module-access.c -+module_access_la_LDFLAGS = $(MODULE_LDFLAGS) -+module_access_la_LIBADD = $(MODULE_LIBADD) -+ - # CLI protocol - - module_cli_la_SOURCES = modules/module-cli.c -diff --git a/src/modules/module-access.c b/src/modules/module-access.c -new file mode 100644 -index 0000000..12deccb ---- /dev/null -+++ b/src/modules/module-access.c -@@ -0,0 +1,474 @@ -+/*** -+ This file is part of PulseAudio. -+ -+ Copyright 2004-2006 Lennart Poettering -+ 2015 Wim Taymans -+ -+ PulseAudio 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.1 of the License, -+ or (at your option) any later version. -+ -+ PulseAudio 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 -+ General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with PulseAudio; if not, see . -+***/ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "module-access-symdef.h" -+ -+PA_MODULE_AUTHOR("Wim Taymans"); -+PA_MODULE_DESCRIPTION("Controls access to server resources"); -+PA_MODULE_VERSION(PACKAGE_VERSION); -+PA_MODULE_LOAD_ONCE(true); -+PA_MODULE_USAGE(""); -+ -+static const char* const valid_modargs[] = { -+ NULL, -+}; -+ -+typedef struct access_policy access_policy; -+typedef struct event_item event_item; -+typedef struct client_data client_data; -+typedef struct userdata userdata; -+ -+typedef pa_hook_result_t (*access_rule_t)(pa_core *c, pa_access_data *d, struct userdata *u); -+ -+struct access_policy { -+ uint32_t index; -+ struct userdata *userdata; -+ -+ access_rule_t rule[PA_ACCESS_HOOK_MAX]; -+}; -+ -+struct event_item { -+ PA_LLIST_FIELDS(event_item); -+ -+ int facility; -+ uint32_t object_index; -+}; -+struct client_data { -+ uint32_t index; -+ uint32_t policy; -+ -+ PA_LLIST_HEAD(event_item, events); -+}; -+ -+struct userdata { -+ pa_core *core; -+ -+ pa_hook_slot *hook[PA_ACCESS_HOOK_MAX]; -+ -+ pa_idxset *policies; -+ uint32_t default_policy; -+ -+ pa_hashmap *clients; -+ pa_hook_slot *client_put_slot; -+ pa_hook_slot *client_proplist_changed_slot; -+ pa_hook_slot *client_unlink_slot; -+}; -+ -+static void add_event(struct client_data *cd, int facility, uint32_t oidx) { -+ event_item *i; -+ -+ i = pa_xnew0(event_item, 1); -+ PA_LLIST_INIT(event_item, i); -+ i->facility = facility; -+ i->object_index = oidx; -+ -+ PA_LLIST_PREPEND(event_item, cd->events, i); -+} -+ -+static event_item *find_event(struct client_data *cd, int facility, uint32_t oidx) { -+ event_item *i; -+ -+ PA_LLIST_FOREACH(i, cd->events) { -+ if (i->facility == facility && i->object_index == oidx) -+ return i; -+ } -+ return NULL; -+} -+ -+static bool remove_event(struct client_data *cd, int facility, uint32_t oidx) { -+ event_item *i = find_event(cd, facility, oidx); -+ if (i) { -+ PA_LLIST_REMOVE(event_item, cd->events, i); -+ pa_xfree(i); -+ return true; -+ } -+ return false; -+} -+ -+static client_data * client_data_new(struct userdata *u, uint32_t index, uint32_t policy) { -+ client_data *cd; -+ -+ cd = pa_xnew0(client_data, 1); -+ cd->index = index; -+ cd->policy = policy; -+ pa_hashmap_put(u->clients, PA_UINT32_TO_PTR(index), cd); -+ pa_log("new client %d with policy %d", index, policy); -+ -+ return cd; -+} -+ -+static void client_data_free(client_data *cd) { -+ event_item *e; -+ -+ while ((e = cd->events)) { -+ PA_LLIST_REMOVE(event_item, cd->events, e); -+ pa_xfree(e); -+ } -+ pa_log("removed client %d", cd->index); -+ pa_xfree(cd); -+} -+ -+static client_data * client_data_get(struct userdata *u, uint32_t index) { -+ return pa_hashmap_get(u->clients, PA_UINT32_TO_PTR(index)); -+} -+ -+static void client_data_remove(struct userdata *u, uint32_t index) { -+ pa_hashmap_remove_and_free(u->clients, PA_UINT32_TO_PTR(index)); -+} -+ -+/* rule checks if the operation on the object is performed by the owner of the object */ -+static pa_hook_result_t rule_check_owner (pa_core *c, pa_access_data *d, struct userdata *u) { -+ pa_hook_result_t result = PA_HOOK_STOP; -+ uint32_t idx = PA_INVALID_INDEX; -+ -+ switch (d->hook) { -+ case PA_ACCESS_HOOK_VIEW_CLIENT: -+ case PA_ACCESS_HOOK_KILL_CLIENT: { -+ idx = d->object_index; -+ break; -+ } -+ -+ case PA_ACCESS_HOOK_VIEW_SINK_INPUT: -+ case PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME: -+ case PA_ACCESS_HOOK_KILL_SINK_INPUT: { -+ const pa_sink_input *si = pa_idxset_get_by_index(c->sink_inputs, d->object_index); -+ idx = (si && si->client) ? si->client->index : PA_INVALID_INDEX; -+ break; -+ } -+ -+ case PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT: -+ case PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME: -+ case PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT: { -+ const pa_source_output *so = pa_idxset_get_by_index(c->source_outputs, d->object_index); -+ idx = (so && so->client) ? so->client->index : PA_INVALID_INDEX; -+ break; -+ } -+ default: -+ break; -+ } -+ if (idx == d->client_index) { -+ pa_log("allow operation %d/%d of same client %d", d->hook, d->object_index, idx); -+ result = PA_HOOK_OK; -+ } -+ else -+ pa_log("blocked operation %d/%d of client %d to client %d", d->hook, d->object_index, idx, d->client_index); -+ -+ return result; -+} -+ -+/* rule allows the operation */ -+static pa_hook_result_t rule_allow (pa_core *c, pa_access_data *d, struct userdata *u) { -+ pa_log("allow operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ return PA_HOOK_OK; -+} -+ -+/* rule blocks the operation */ -+static pa_hook_result_t rule_block (pa_core *c, pa_access_data *d, struct userdata *u) { -+ pa_log("blocked operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ return PA_HOOK_STOP; -+} -+ -+static access_policy *access_policy_new(struct userdata *u, bool allow_all) { -+ access_policy *ap; -+ int i; -+ -+ ap = pa_xnew0(access_policy, 1); -+ ap->userdata = u; -+ for (i = 0; i < PA_ACCESS_HOOK_MAX; i++) -+ ap->rule[i] = allow_all ? rule_allow : rule_block; -+ -+ pa_idxset_put(u->policies, ap, &ap->index); -+ -+ return ap; -+} -+ -+static void access_policy_free(access_policy *ap) { -+ pa_idxset_remove_by_index(ap->userdata->policies, ap->index); -+ pa_xfree(ap); -+} -+ -+static pa_hook_result_t check_access (pa_core *c, pa_access_data *d, struct userdata *u) { -+ access_policy *ap; -+ access_rule_t rule; -+ client_data *cd = client_data_get(u, d->client_index); -+ -+ /* unknown client */ -+ if (cd == NULL) -+ return PA_HOOK_STOP; -+ -+ ap = pa_idxset_get_by_index(u->policies, cd->policy); -+ -+ rule = ap->rule[d->hook]; -+ if (rule) -+ return rule(c, d, u); -+ -+ return PA_HOOK_STOP; -+} -+ -+static const pa_access_hook_t event_hook[PA_SUBSCRIPTION_EVENT_FACILITY_MASK+1] = { -+ [PA_SUBSCRIPTION_EVENT_SINK] = PA_ACCESS_HOOK_VIEW_SINK, -+ [PA_SUBSCRIPTION_EVENT_SOURCE] = PA_ACCESS_HOOK_VIEW_SOURCE, -+ [PA_SUBSCRIPTION_EVENT_SINK_INPUT] = PA_ACCESS_HOOK_VIEW_SINK_INPUT, -+ [PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT] = PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT, -+ [PA_SUBSCRIPTION_EVENT_MODULE] = PA_ACCESS_HOOK_VIEW_MODULE, -+ [PA_SUBSCRIPTION_EVENT_CLIENT] = PA_ACCESS_HOOK_VIEW_CLIENT, -+ [PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE] = PA_ACCESS_HOOK_VIEW_SAMPLE, -+ [PA_SUBSCRIPTION_EVENT_SERVER] = PA_ACCESS_HOOK_VIEW_SERVER, -+ [PA_SUBSCRIPTION_EVENT_CARD] = PA_ACCESS_HOOK_VIEW_CARD -+}; -+ -+ -+ -+static pa_hook_result_t filter_event (pa_core *c, pa_access_data *d, struct userdata *u) { -+ int facility; -+ client_data *cd; -+ -+ facility = d->event & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; -+ -+ cd = client_data_get (u, d->client_index); -+ /* unknown client destination, block event */ -+ if (cd == NULL) -+ goto block; -+ -+ switch (d->event & PA_SUBSCRIPTION_EVENT_TYPE_MASK) { -+ case PA_SUBSCRIPTION_EVENT_REMOVE: -+ /* if the client saw this object before, let the event go through */ -+ if (remove_event(cd, facility, d->object_index)) { -+ pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ return PA_HOOK_OK; -+ } -+ break; -+ -+ case PA_SUBSCRIPTION_EVENT_CHANGE: -+ /* if the client saw this object before, let it go through */ -+ if (find_event(cd, facility, d->object_index)) { -+ pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ return PA_HOOK_OK; -+ } -+ -+ /* fallthrough to do hook check and register event */ -+ case PA_SUBSCRIPTION_EVENT_NEW: { -+ pa_access_data data = *d; -+ -+ /* new object, check if the client is allowed to inspect it */ -+ data.hook = event_hook[facility]; -+ if (data.hook && pa_hook_fire(&c->access[data.hook], &data) == PA_HOOK_OK) { -+ /* client can inspect the object, remember for later */ -+ add_event(cd, facility, d->object_index); -+ pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ return PA_HOOK_OK; -+ } -+ break; -+ } -+ default: -+ break; -+ } -+ -+block: -+ pa_log("blocked event %02x/%d for client %d", d->event, d->object_index, d->client_index); -+ return PA_HOOK_STOP; -+} -+ -+static uint32_t find_policy_for_client (struct userdata *u, pa_client *cl) { -+ char *s; -+ -+ s = pa_proplist_to_string(cl->proplist); -+ pa_log ("client proplist %s", s); -+ pa_xfree(s); -+ -+ return u->default_policy; -+} -+ -+static pa_hook_result_t client_put_cb(pa_core *c, pa_object *o, struct userdata *u) { -+ pa_client *cl; -+ uint32_t policy; -+ -+ pa_assert(c); -+ pa_object_assert_ref(o); -+ -+ cl = (pa_client *) o; -+ pa_assert(cl); -+ -+ policy = find_policy_for_client(u, cl); -+ -+ client_data_new(u, cl->index, policy); -+ -+ return PA_HOOK_OK; -+} -+ -+static pa_hook_result_t client_proplist_changed_cb(pa_core *c, pa_object *o, struct userdata *u) { -+ pa_client *cl; -+ client_data *cd; -+ uint32_t policy; -+ -+ pa_assert(c); -+ pa_object_assert_ref(o); -+ -+ cl = (pa_client *) o; -+ pa_assert(cl); -+ -+ cd = client_data_get (u, cl->index); -+ if (cd == NULL) -+ return PA_HOOK_OK; -+ -+ policy = find_policy_for_client(u, cl); -+ cd->policy = policy; -+ -+ return PA_HOOK_OK; -+} -+ -+static pa_hook_result_t client_unlink_cb(pa_core *c, pa_object *o, struct userdata *u) { -+ pa_client *cl; -+ -+ pa_assert(c); -+ pa_object_assert_ref(o); -+ -+ cl = (pa_client *) o; -+ pa_assert(cl); -+ -+ client_data_remove(u, cl->index); -+ -+ return PA_HOOK_OK; -+} -+ -+ -+int pa__init(pa_module*m) { -+ pa_modargs *ma = NULL; -+ struct userdata *u; -+ int i; -+ access_policy *ap; -+ -+ pa_assert(m); -+ -+ if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { -+ pa_log("Failed to parse module arguments"); -+ goto fail; -+ } -+ -+ u = pa_xnew0(struct userdata, 1); -+ u->core = m->core; -+ m->userdata = u; -+ -+ u->policies = pa_idxset_new (NULL, NULL); -+ u->clients = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, -+ (pa_free_cb_t) client_data_free); -+ -+ u->client_put_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) client_put_cb, u); -+ u->client_proplist_changed_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) client_proplist_changed_cb, u); -+ u->client_unlink_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) client_unlink_cb, u); -+ -+ for (i = 0; i < PA_ACCESS_HOOK_MAX; i++) { -+ pa_hook_cb_t cb; -+ -+ if (i == PA_ACCESS_HOOK_FILTER_SUBSCRIBE_EVENT) -+ cb = (pa_hook_cb_t) filter_event; -+ else -+ cb = (pa_hook_cb_t) check_access; -+ -+ u->hook[i] = pa_hook_connect(&u->core->access[i], PA_HOOK_EARLY - 1, cb, u); -+ } -+ -+ ap = access_policy_new(u, false); -+ -+ ap->rule[PA_ACCESS_HOOK_VIEW_SINK] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SOURCE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SERVER] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_MODULE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_CARD] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_STAT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SAMPLE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_PLAY_SAMPLE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_CONNECT_PLAYBACK] = rule_allow; -+ -+ ap->rule[PA_ACCESS_HOOK_KILL_CLIENT] = rule_check_owner; -+ -+ ap->rule[PA_ACCESS_HOOK_CREATE_SINK_INPUT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SINK_INPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_KILL_SINK_INPUT] = rule_check_owner; -+ -+ ap->rule[PA_ACCESS_HOOK_CREATE_SOURCE_OUTPUT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT] = rule_check_owner; -+ -+ u->default_policy = ap->index; -+ -+ pa_modargs_free(ma); -+ return 0; -+ -+fail: -+ pa__done(m); -+ -+ if (ma) -+ pa_modargs_free(ma); -+ return -1; -+} -+ -+void pa__done(pa_module*m) { -+ struct userdata* u; -+ int i; -+ -+ pa_assert(m); -+ -+ if (!(u = m->userdata)) -+ return; -+ -+ for (i = 0; i < PA_ACCESS_HOOK_MAX; i++) { -+ if (u->hook[i]) -+ pa_hook_slot_free(u->hook[i]); -+ } -+ -+ if (u->policies) -+ pa_idxset_free(u->policies, (pa_free_cb_t) access_policy_free); -+ -+ if (u->client_put_slot) -+ pa_hook_slot_free(u->client_put_slot); -+ if (u->client_proplist_changed_slot) -+ pa_hook_slot_free(u->client_proplist_changed_slot); -+ if (u->client_unlink_slot) -+ pa_hook_slot_free(u->client_unlink_slot); -+ -+ if (u->clients) -+ pa_hashmap_free(u->clients); -+ -+ pa_xfree(u); -+} --- -2.9.3 - diff --git a/0007-module-access-add-async-handler-for-record.patch b/0007-module-access-add-async-handler-for-record.patch deleted file mode 100644 index a729d74..0000000 --- a/0007-module-access-add-async-handler-for-record.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 8f43958cf8e0aa7ba45cddbae3952e831fc9a08f Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Thu, 14 Jul 2016 17:38:01 +0200 -Subject: [PATCH 07/18] module-access: add async handler for record - -Use an async handler to check for record access. This also shows how -we need to remember the result for when the access check is issued -again after the async reply. ---- - src/modules/module-access.c | 65 ++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 61 insertions(+), 4 deletions(-) - -diff --git a/src/modules/module-access.c b/src/modules/module-access.c -index 12deccb..290d052 100644 ---- a/src/modules/module-access.c -+++ b/src/modules/module-access.c -@@ -30,6 +30,8 @@ - #include - - #include -+#include -+#include - - #include - #include -@@ -71,11 +73,10 @@ struct event_item { - int facility; - uint32_t object_index; - }; --struct client_data { -- uint32_t index; -- uint32_t policy; - -- PA_LLIST_HEAD(event_item, events); -+struct async_cache { -+ bool checked; -+ bool granted; - }; - - struct userdata { -@@ -92,6 +93,20 @@ struct userdata { - pa_hook_slot *client_unlink_slot; - }; - -+struct client_data { -+ struct userdata *u; -+ -+ uint32_t index; -+ uint32_t policy; -+ -+ struct async_cache cached[PA_ACCESS_HOOK_MAX]; -+ pa_time_event *time_event; -+ pa_access_data *access_data; -+ -+ PA_LLIST_HEAD(event_item, events); -+}; -+ -+ - static void add_event(struct client_data *cd, int facility, uint32_t oidx) { - event_item *i; - -@@ -123,12 +138,29 @@ static bool remove_event(struct client_data *cd, int facility, uint32_t oidx) { - return false; - } - -+static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *data) { -+ client_data *cd = data; -+ struct userdata *u = cd->u; -+ pa_access_data *d = cd->access_data; -+ -+ pa_log("async check finished of operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ u->core->mainloop->time_restart(cd->time_event, NULL); -+ -+ cd->cached[d->hook].checked = true; -+ /* this should be granted or denied */ -+ cd->cached[d->hook].granted = true; -+ -+ d->complete_cb (d, cd->cached[d->hook].granted); -+} -+ - static client_data * client_data_new(struct userdata *u, uint32_t index, uint32_t policy) { - client_data *cd; - - cd = pa_xnew0(client_data, 1); -+ cd->u = u; - cd->index = index; - cd->policy = policy; -+ cd->time_event = pa_core_rttime_new(u->core, PA_USEC_INVALID, timeout_cb, cd); - pa_hashmap_put(u->clients, PA_UINT32_TO_PTR(index), cd); - pa_log("new client %d with policy %d", index, policy); - -@@ -143,6 +175,7 @@ static void client_data_free(client_data *cd) { - pa_xfree(e); - } - pa_log("removed client %d", cd->index); -+ cd->u->core->mainloop->time_free(cd->time_event); - pa_xfree(cd); - } - -@@ -206,6 +239,27 @@ static pa_hook_result_t rule_block (pa_core *c, pa_access_data *d, struct userda - return PA_HOOK_STOP; - } - -+ -+/* rule asynchronously checks the operation */ -+static pa_hook_result_t rule_check_async (pa_core *c, pa_access_data *d, struct userdata *u) { -+ pa_usec_t now; -+ client_data *cd = client_data_get(u, d->client_index); -+ -+ pa_log("async check of operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ -+ if (cd->cached[d->hook].checked) -+ return cd->cached[d->hook].granted ? PA_HOOK_OK : PA_HOOK_STOP; -+ -+ /* save access_data */ -+ cd->access_data = d; -+ -+ now = pa_rtclock_now(); -+ pa_core_rttime_restart (u->core, cd->time_event, now + 2 * PA_USEC_PER_SEC); -+ -+ return PA_HOOK_CANCEL; -+} -+ -+ - static access_policy *access_policy_new(struct userdata *u, bool allow_all) { - access_policy *ap; - int i; -@@ -418,6 +472,9 @@ int pa__init(pa_module*m) { - ap->rule[PA_ACCESS_HOOK_PLAY_SAMPLE] = rule_allow; - ap->rule[PA_ACCESS_HOOK_CONNECT_PLAYBACK] = rule_allow; - -+ ap->rule[PA_ACCESS_HOOK_CONNECT_RECORD] = rule_check_async; -+ -+ ap->rule[PA_ACCESS_HOOK_VIEW_CLIENT] = rule_check_owner; - ap->rule[PA_ACCESS_HOOK_KILL_CLIENT] = rule_check_owner; - - ap->rule[PA_ACCESS_HOOK_CREATE_SINK_INPUT] = rule_allow; --- -2.9.3 - diff --git a/0008-module-access-use-the-auth-hook-and-pid.patch b/0008-module-access-use-the-auth-hook-and-pid.patch deleted file mode 100644 index 32e69ed..0000000 --- a/0008-module-access-use-the-auth-hook-and-pid.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 8fcf8065b8329ab9abe14ecddc1040e14adc6461 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Fri, 15 Jul 2016 12:36:45 +0200 -Subject: [PATCH 08/18] module-access: use the auth hook and pid - -Connect to the client_auth hook and also check the pid from the -credentials to find the right policy for a client. ---- - src/modules/module-access.c | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - -diff --git a/src/modules/module-access.c b/src/modules/module-access.c -index 290d052..c00612a 100644 ---- a/src/modules/module-access.c -+++ b/src/modules/module-access.c -@@ -89,6 +89,7 @@ struct userdata { - - pa_hashmap *clients; - pa_hook_slot *client_put_slot; -+ pa_hook_slot *client_auth_slot; - pa_hook_slot *client_proplist_changed_slot; - pa_hook_slot *client_unlink_slot; - }; -@@ -368,6 +369,9 @@ static uint32_t find_policy_for_client (struct userdata *u, pa_client *cl) { - pa_log ("client proplist %s", s); - pa_xfree(s); - -+ if (cl->creds_valid) { -+ pa_log ("client has trusted pid %d", cl->creds.pid); -+ } - return u->default_policy; - } - -@@ -381,6 +385,8 @@ static pa_hook_result_t client_put_cb(pa_core *c, pa_object *o, struct userdata - cl = (pa_client *) o; - pa_assert(cl); - -+ /* when we get here, the client just connected and is not yet authenticated -+ * we should probably install a policy that denies all access */ - policy = find_policy_for_client(u, cl); - - client_data_new(u, cl->index, policy); -@@ -388,6 +394,27 @@ static pa_hook_result_t client_put_cb(pa_core *c, pa_object *o, struct userdata - return PA_HOOK_OK; - } - -+static pa_hook_result_t client_auth_cb(pa_core *c, pa_object *o, struct userdata *u) { -+ pa_client *cl; -+ client_data *cd; -+ uint32_t policy; -+ -+ pa_assert(c); -+ pa_object_assert_ref(o); -+ -+ cl = (pa_client *) o; -+ pa_assert(cl); -+ -+ cd = client_data_get (u, cl->index); -+ if (cd == NULL) -+ return PA_HOOK_OK; -+ -+ policy = find_policy_for_client(u, cl); -+ cd->policy = policy; -+ -+ return PA_HOOK_OK; -+} -+ - static pa_hook_result_t client_proplist_changed_cb(pa_core *c, pa_object *o, struct userdata *u) { - pa_client *cl; - client_data *cd; -@@ -446,6 +473,7 @@ int pa__init(pa_module*m) { - (pa_free_cb_t) client_data_free); - - u->client_put_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) client_put_cb, u); -+ u->client_auth_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_AUTH], PA_HOOK_EARLY, (pa_hook_cb_t) client_auth_cb, u); - u->client_proplist_changed_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) client_proplist_changed_cb, u); - u->client_unlink_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) client_unlink_cb, u); - -@@ -519,6 +547,8 @@ void pa__done(pa_module*m) { - - if (u->client_put_slot) - pa_hook_slot_free(u->client_put_slot); -+ if (u->client_auth_slot) -+ pa_hook_slot_free(u->client_auth_slot); - if (u->client_proplist_changed_slot) - pa_hook_slot_free(u->client_proplist_changed_slot); - if (u->client_unlink_slot) --- -2.9.3 - diff --git a/0009-pulsecore-Move-pa_core-structure-into-its-own-header.patch b/0009-pulsecore-Move-pa_core-structure-into-its-own-header.patch deleted file mode 100644 index ef13b29..0000000 --- a/0009-pulsecore-Move-pa_core-structure-into-its-own-header.patch +++ /dev/null @@ -1,1619 +0,0 @@ -From 6347cd3e72347d8698af0b48fc626fa43f4e218f Mon Sep 17 00:00:00 2001 -From: Arun Raghavan -Date: Mon, 4 Jul 2016 13:57:16 +0530 -Subject: [PATCH 09/18] pulsecore: Move pa_core structure into its own header - -The idea is to allow some parts of the code to use pa_core as an opaque -structure and access required members via API, over which we can then -perform some form of access control - -Signed-off-by: Arun Raghavan ---- - src/Makefile.am | 1 + - src/daemon/main.c | 1 + - src/daemon/server-lookup.c | 1 + - src/modules/alsa/alsa-sink.c | 1 + - src/modules/alsa/alsa-source.c | 1 + - src/modules/alsa/alsa-ucm.c | 1 + - src/modules/alsa/module-alsa-card.c | 1 + - src/modules/bluetooth/backend-native.c | 1 + - src/modules/bluetooth/bluez4-util.c | 1 + - src/modules/bluetooth/bluez5-util.c | 1 + - src/modules/bluetooth/module-bluetooth-policy.c | 1 + - src/modules/bluetooth/module-bluez4-device.c | 1 + - src/modules/bluetooth/module-bluez5-device.c | 1 + - src/modules/bluetooth/module-bluez5-discover.c | 1 + - src/modules/dbus/iface-card.c | 1 + - src/modules/dbus/iface-client.c | 1 + - src/modules/dbus/iface-core.c | 1 + - src/modules/dbus/iface-device-port.c | 1 + - src/modules/dbus/iface-device.c | 1 + - src/modules/dbus/iface-memstats.c | 1 + - src/modules/dbus/iface-module.c | 1 + - src/modules/dbus/iface-sample.c | 1 + - src/modules/dbus/iface-stream.c | 1 + - src/modules/dbus/module-dbus-protocol.c | 1 + - src/modules/echo-cancel/adrian.c | 1 + - src/modules/echo-cancel/module-echo-cancel.c | 1 + - src/modules/gconf/module-gconf.c | 1 + - src/modules/jack/module-jack-sink.c | 1 + - src/modules/jack/module-jack-source.c | 1 + - src/modules/module-access.c | 1 + - src/modules/module-allow-passthrough.c | 1 + - src/modules/module-always-sink.c | 1 + - src/modules/module-augment-properties.c | 1 + - src/modules/module-card-restore.c | 1 + - src/modules/module-cli.c | 1 + - src/modules/module-combine-sink.c | 1 + - src/modules/module-default-device-restore.c | 1 + - src/modules/module-device-manager.c | 1 + - src/modules/module-device-restore.c | 1 + - src/modules/module-equalizer-sink.c | 1 + - src/modules/module-esound-sink.c | 1 + - src/modules/module-filter-apply.c | 1 + - src/modules/module-filter-heuristics.c | 1 + - src/modules/module-intended-roles.c | 1 + - src/modules/module-ladspa-sink.c | 1 + - src/modules/module-lirc.c | 1 + - src/modules/module-loopback.c | 1 + - src/modules/module-match.c | 1 + - src/modules/module-mmkbd-evdev.c | 1 + - src/modules/module-native-protocol-fd.c | 1 + - src/modules/module-null-sink.c | 1 + - src/modules/module-null-source.c | 1 + - src/modules/module-pipe-sink.c | 1 + - src/modules/module-pipe-source.c | 1 + - src/modules/module-position-event-sounds.c | 1 + - src/modules/module-protocol-stub.c | 1 + - src/modules/module-rescue-streams.c | 1 + - src/modules/module-role-cork.c | 1 + - src/modules/module-role-ducking.c | 1 + - src/modules/module-rygel-media-server.c | 1 + - src/modules/module-sine-source.c | 1 + - src/modules/module-sine.c | 1 + - src/modules/module-stream-restore.c | 1 + - src/modules/module-suspend-on-idle.c | 1 + - src/modules/module-switch-on-connect.c | 1 + - src/modules/module-switch-on-port-available.c | 1 + - src/modules/module-systemd-login.c | 1 + - src/modules/module-tunnel-sink-new.c | 1 + - src/modules/module-tunnel-source-new.c | 1 + - src/modules/module-tunnel.c | 1 + - src/modules/module-udev-detect.c | 1 + - src/modules/module-virtual-sink.c | 1 + - src/modules/module-virtual-source.c | 1 + - src/modules/module-virtual-surround-sink.c | 1 + - src/modules/module-zeroconf-discover.c | 1 + - src/modules/module-zeroconf-publish.c | 1 + - src/modules/oss/module-oss.c | 1 + - src/modules/raop/module-raop-discover.c | 1 + - src/modules/raop/module-raop-sink.c | 1 + - src/modules/raop/raop_client.c | 1 + - src/modules/rtp/module-rtp-recv.c | 1 + - src/modules/rtp/module-rtp-send.c | 1 + - src/modules/stream-interaction.c | 1 + - src/modules/x11/module-x11-cork-request.c | 1 + - src/modules/x11/module-x11-xsmp.c | 1 + - src/pulsecore/card.c | 1 + - src/pulsecore/cli-command.c | 1 + - src/pulsecore/cli-text.c | 1 + - src/pulsecore/client.c | 1 + - src/pulsecore/core-scache.c | 1 + - src/pulsecore/core-struct.h | 103 ++++++++++++++++++++++++ - src/pulsecore/core-subscribe.c | 1 + - src/pulsecore/core.c | 1 + - src/pulsecore/core.h | 76 ----------------- - src/pulsecore/dbus-shared.c | 1 + - src/pulsecore/device-port.c | 1 + - src/pulsecore/module.c | 1 + - src/pulsecore/namereg.c | 1 + - src/pulsecore/play-memchunk.c | 1 + - src/pulsecore/protocol-esound.c | 1 + - src/pulsecore/protocol-http.c | 1 + - src/pulsecore/protocol-native.c | 1 + - src/pulsecore/protocol-simple.c | 1 + - src/pulsecore/shared.c | 1 + - src/pulsecore/sink-input.c | 1 + - src/pulsecore/sink.c | 1 + - src/pulsecore/sound-file-stream.c | 1 + - src/pulsecore/source-output.c | 1 + - src/pulsecore/source.c | 1 + - src/pulsecore/x11wrap.c | 1 + - 110 files changed, 211 insertions(+), 76 deletions(-) - create mode 100644 src/pulsecore/core-struct.h - -diff --git a/src/Makefile.am b/src/Makefile.am -index 7c66064..70bc848 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -960,6 +960,7 @@ libpulsecore_@PA_MAJORMINOR@_la_SOURCES = \ - pulsecore/core-scache.c pulsecore/core-scache.h \ - pulsecore/core-subscribe.c pulsecore/core-subscribe.h \ - pulsecore/core.c pulsecore/core.h \ -+ pulsecore/core-struct.h \ - pulsecore/hook-list.c pulsecore/hook-list.h \ - pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \ - pulsecore/modargs.c pulsecore/modargs.h \ -diff --git a/src/daemon/main.c b/src/daemon/main.c -index dc5e5bc..cb69f17 100644 ---- a/src/daemon/main.c -+++ b/src/daemon/main.c -@@ -73,6 +73,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c -index ca390c7..b5c53e4 100644 ---- a/src/daemon/server-lookup.c -+++ b/src/daemon/server-lookup.c -@@ -27,6 +27,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 886c735..41ef1ae 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -38,6 +38,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index b788df2..4a3f407 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -33,6 +33,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index b42c040..227ed7d 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -40,6 +40,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c -index 4f1236e..b6ac865 100644 ---- a/src/modules/alsa/module-alsa-card.c -+++ b/src/modules/alsa/module-alsa-card.c -@@ -23,6 +23,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c -index cf88126..f78cebc 100644 ---- a/src/modules/bluetooth/backend-native.c -+++ b/src/modules/bluetooth/backend-native.c -@@ -22,6 +22,7 @@ - #endif - - #include -+#include - #include - #include - #include -diff --git a/src/modules/bluetooth/bluez4-util.c b/src/modules/bluetooth/bluez4-util.c -index 542ce35..c582b95 100644 ---- a/src/modules/bluetooth/bluez4-util.c -+++ b/src/modules/bluetooth/bluez4-util.c -@@ -23,6 +23,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c -index 7d63f35..dac176b 100644 ---- a/src/modules/bluetooth/bluez5-util.c -+++ b/src/modules/bluetooth/bluez5-util.c -@@ -26,6 +26,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c -index df702cc..aa9fa4a 100644 ---- a/src/modules/bluetooth/module-bluetooth-policy.c -+++ b/src/modules/bluetooth/module-bluetooth-policy.c -@@ -26,6 +26,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/bluetooth/module-bluez4-device.c b/src/modules/bluetooth/module-bluez4-device.c -index ac4ed63..3f2e70f 100644 ---- a/src/modules/bluetooth/module-bluez4-device.c -+++ b/src/modules/bluetooth/module-bluez4-device.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c -index 065fcaa..0dbe6f3 100644 ---- a/src/modules/bluetooth/module-bluez5-device.c -+++ b/src/modules/bluetooth/module-bluez5-device.c -@@ -30,6 +30,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/bluetooth/module-bluez5-discover.c b/src/modules/bluetooth/module-bluez5-discover.c -index 080e5d0..a5a0b45 100644 ---- a/src/modules/bluetooth/module-bluez5-discover.c -+++ b/src/modules/bluetooth/module-bluez5-discover.c -@@ -22,6 +22,7 @@ - #endif - - #include -+#include - #include - #include - #include -diff --git a/src/modules/dbus/iface-card.c b/src/modules/dbus/iface-card.c -index 1b705ba..ffcbc7a 100644 ---- a/src/modules/dbus/iface-card.c -+++ b/src/modules/dbus/iface-card.c -@@ -23,6 +23,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/dbus/iface-client.c b/src/modules/dbus/iface-client.c -index 455ea45..3f3003f 100644 ---- a/src/modules/dbus/iface-client.c -+++ b/src/modules/dbus/iface-client.c -@@ -24,6 +24,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c -index 508913d..bfabd61 100644 ---- a/src/modules/dbus/iface-core.c -+++ b/src/modules/dbus/iface-core.c -@@ -28,6 +28,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/dbus/iface-device-port.c b/src/modules/dbus/iface-device-port.c -index 4892443..96a2abd 100644 ---- a/src/modules/dbus/iface-device-port.c -+++ b/src/modules/dbus/iface-device-port.c -@@ -23,6 +23,7 @@ - - #include - -+#include - #include - #include - -diff --git a/src/modules/dbus/iface-device.c b/src/modules/dbus/iface-device.c -index 2c370a8..abaa42b 100644 ---- a/src/modules/dbus/iface-device.c -+++ b/src/modules/dbus/iface-device.c -@@ -21,6 +21,7 @@ - #include - #endif - -+#include - #include - #include - #include -diff --git a/src/modules/dbus/iface-memstats.c b/src/modules/dbus/iface-memstats.c -index cd1d7ea..6ed4b07 100644 ---- a/src/modules/dbus/iface-memstats.c -+++ b/src/modules/dbus/iface-memstats.c -@@ -23,6 +23,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/dbus/iface-module.c b/src/modules/dbus/iface-module.c -index 222cd73..a6fdf50 100644 ---- a/src/modules/dbus/iface-module.c -+++ b/src/modules/dbus/iface-module.c -@@ -21,6 +21,7 @@ - #include - #endif - -+#include - #include - #include - #include -diff --git a/src/modules/dbus/iface-sample.c b/src/modules/dbus/iface-sample.c -index 61f2ba0..accdf46 100644 ---- a/src/modules/dbus/iface-sample.c -+++ b/src/modules/dbus/iface-sample.c -@@ -21,6 +21,7 @@ - #include - #endif - -+#include - #include - #include - #include -diff --git a/src/modules/dbus/iface-stream.c b/src/modules/dbus/iface-stream.c -index ade62ca..76bbeb0 100644 ---- a/src/modules/dbus/iface-stream.c -+++ b/src/modules/dbus/iface-stream.c -@@ -22,6 +22,7 @@ - #include - #endif - -+#include - #include - #include - #include -diff --git a/src/modules/dbus/module-dbus-protocol.c b/src/modules/dbus/module-dbus-protocol.c -index 8079d6b..abd340a 100644 ---- a/src/modules/dbus/module-dbus-protocol.c -+++ b/src/modules/dbus/module-dbus-protocol.c -@@ -30,6 +30,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/echo-cancel/adrian.c b/src/modules/echo-cancel/adrian.c -index 3c47fae..870a1fe 100644 ---- a/src/modules/echo-cancel/adrian.c -+++ b/src/modules/echo-cancel/adrian.c -@@ -29,6 +29,7 @@ - - #include - -+#include - #include - - #include "echo-cancel.h" -diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c -index dfd05b6..f3f24ed 100644 ---- a/src/modules/echo-cancel/module-echo-cancel.c -+++ b/src/modules/echo-cancel/module-echo-cancel.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c -index 1e1b855..5baa1ae 100644 ---- a/src/modules/gconf/module-gconf.c -+++ b/src/modules/gconf/module-gconf.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/jack/module-jack-sink.c b/src/modules/jack/module-jack-sink.c -index 4d31493..22dbbad 100644 ---- a/src/modules/jack/module-jack-sink.c -+++ b/src/modules/jack/module-jack-sink.c -@@ -33,6 +33,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/jack/module-jack-source.c b/src/modules/jack/module-jack-source.c -index e45f304..ce5a096 100644 ---- a/src/modules/jack/module-jack-source.c -+++ b/src/modules/jack/module-jack-source.c -@@ -33,6 +33,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-access.c b/src/modules/module-access.c -index c00612a..39e2f0e 100644 ---- a/src/modules/module-access.c -+++ b/src/modules/module-access.c -@@ -34,6 +34,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-allow-passthrough.c b/src/modules/module-allow-passthrough.c -index 4b801e4..45e7a41 100644 ---- a/src/modules/module-allow-passthrough.c -+++ b/src/modules/module-allow-passthrough.c -@@ -26,6 +26,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-always-sink.c b/src/modules/module-always-sink.c -index 12f63f7..a7f3568 100644 ---- a/src/modules/module-always-sink.c -+++ b/src/modules/module-always-sink.c -@@ -24,6 +24,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-augment-properties.c b/src/modules/module-augment-properties.c -index 541f0e7..4608d45 100644 ---- a/src/modules/module-augment-properties.c -+++ b/src/modules/module-augment-properties.c -@@ -28,6 +28,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c -index 3c0307b..ff6066f 100644 ---- a/src/modules/module-card-restore.c -+++ b/src/modules/module-card-restore.c -@@ -33,6 +33,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-cli.c b/src/modules/module-cli.c -index a69ad4a..b23519d 100644 ---- a/src/modules/module-cli.c -+++ b/src/modules/module-cli.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - - #include "module-cli-symdef.h" -diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c -index 250240a..4fadbb9 100644 ---- a/src/modules/module-combine-sink.c -+++ b/src/modules/module-combine-sink.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-default-device-restore.c b/src/modules/module-default-device-restore.c -index d76e28e..4b169bb 100644 ---- a/src/modules/module-default-device-restore.c -+++ b/src/modules/module-default-device-restore.c -@@ -28,6 +28,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c -index 2a0a67f..17406c3 100644 ---- a/src/modules/module-device-manager.c -+++ b/src/modules/module-device-manager.c -@@ -34,6 +34,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c -index 8d7b34b..f150dbd 100644 ---- a/src/modules/module-device-restore.c -+++ b/src/modules/module-device-restore.c -@@ -37,6 +37,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c -index 9c25f3f..8c50468 100644 ---- a/src/modules/module-equalizer-sink.c -+++ b/src/modules/module-equalizer-sink.c -@@ -46,6 +46,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c -index 2ce0c85..f304c97 100644 ---- a/src/modules/module-esound-sink.c -+++ b/src/modules/module-esound-sink.c -@@ -48,6 +48,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-filter-apply.c b/src/modules/module-filter-apply.c -index 364d68b..ceeb541 100644 ---- a/src/modules/module-filter-apply.c -+++ b/src/modules/module-filter-apply.c -@@ -26,6 +26,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-filter-heuristics.c b/src/modules/module-filter-heuristics.c -index 423e873..15baa1c 100644 ---- a/src/modules/module-filter-heuristics.c -+++ b/src/modules/module-filter-heuristics.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c -index 60ec7e9..e083c11 100644 ---- a/src/modules/module-intended-roles.c -+++ b/src/modules/module-intended-roles.c -@@ -24,6 +24,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c -index c11fa5e..3602830 100644 ---- a/src/modules/module-ladspa-sink.c -+++ b/src/modules/module-ladspa-sink.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c -index d63fdbd..7c325da 100644 ---- a/src/modules/module-lirc.c -+++ b/src/modules/module-lirc.c -@@ -30,6 +30,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c -index 9410c98..75da911 100644 ---- a/src/modules/module-loopback.c -+++ b/src/modules/module-loopback.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - #include - - #include -diff --git a/src/modules/module-match.c b/src/modules/module-match.c -index 559687c..f371139 100644 ---- a/src/modules/module-match.c -+++ b/src/modules/module-match.c -@@ -36,6 +36,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c -index 6c9cf34..818a502 100644 ---- a/src/modules/module-mmkbd-evdev.c -+++ b/src/modules/module-mmkbd-evdev.c -@@ -32,6 +32,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-native-protocol-fd.c b/src/modules/module-native-protocol-fd.c -index 5fd7f6a..c951bc6 100644 ---- a/src/modules/module-native-protocol-fd.c -+++ b/src/modules/module-native-protocol-fd.c -@@ -24,6 +24,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c -index b8157e8..be3c98f 100644 ---- a/src/modules/module-null-sink.c -+++ b/src/modules/module-null-sink.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-null-source.c b/src/modules/module-null-source.c -index a75a04f..a791883 100644 ---- a/src/modules/module-null-source.c -+++ b/src/modules/module-null-source.c -@@ -31,6 +31,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c -index da65021..0b32f0d 100644 ---- a/src/modules/module-pipe-sink.c -+++ b/src/modules/module-pipe-sink.c -@@ -35,6 +35,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c -index f39fc55..4b651cc 100644 ---- a/src/modules/module-pipe-source.c -+++ b/src/modules/module-pipe-source.c -@@ -35,6 +35,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-position-event-sounds.c b/src/modules/module-position-event-sounds.c -index fb9f5b3..ef03786 100644 ---- a/src/modules/module-position-event-sounds.c -+++ b/src/modules/module-position-event-sounds.c -@@ -32,6 +32,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c -index 5a183c8..8fd4392 100644 ---- a/src/modules/module-protocol-stub.c -+++ b/src/modules/module-protocol-stub.c -@@ -32,6 +32,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c -index 60ac1c4..e844e16 100644 ---- a/src/modules/module-rescue-streams.c -+++ b/src/modules/module-rescue-streams.c -@@ -24,6 +24,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-role-cork.c b/src/modules/module-role-cork.c -index d71cc38..d11be8c 100644 ---- a/src/modules/module-role-cork.c -+++ b/src/modules/module-role-cork.c -@@ -23,6 +23,7 @@ - - #include - #include -+#include - #include - - #include "module-role-cork-symdef.h" -diff --git a/src/modules/module-role-ducking.c b/src/modules/module-role-ducking.c -index add2d36..af3e98c 100644 ---- a/src/modules/module-role-ducking.c -+++ b/src/modules/module-role-ducking.c -@@ -23,6 +23,7 @@ - - #include - #include -+#include - #include - - #include "module-role-ducking-symdef.h" -diff --git a/src/modules/module-rygel-media-server.c b/src/modules/module-rygel-media-server.c -index e2c2e6f..0737fa9 100644 ---- a/src/modules/module-rygel-media-server.c -+++ b/src/modules/module-rygel-media-server.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-sine-source.c b/src/modules/module-sine-source.c -index cdeb2c0..a3be322 100644 ---- a/src/modules/module-sine-source.c -+++ b/src/modules/module-sine-source.c -@@ -32,6 +32,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c -index d56fae5..a95cf79 100644 ---- a/src/modules/module-sine.c -+++ b/src/modules/module-sine.c -@@ -25,6 +25,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c -index d1c2597..75ca729 100644 ---- a/src/modules/module-stream-restore.c -+++ b/src/modules/module-stream-restore.c -@@ -35,6 +35,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c -index a284f85..030de4d 100644 ---- a/src/modules/module-suspend-on-idle.c -+++ b/src/modules/module-suspend-on-idle.c -@@ -26,6 +26,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c -index c844add..f3171e9 100644 ---- a/src/modules/module-switch-on-connect.c -+++ b/src/modules/module-switch-on-connect.c -@@ -25,6 +25,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c -index b9a0f3b..ee787cc 100644 ---- a/src/modules/module-switch-on-port-available.c -+++ b/src/modules/module-switch-on-port-available.c -@@ -23,6 +23,7 @@ - #endif - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-systemd-login.c b/src/modules/module-systemd-login.c -index d15bee5..62eeb4c 100644 ---- a/src/modules/module-systemd-login.c -+++ b/src/modules/module-systemd-login.c -@@ -32,6 +32,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c -index 92f99df..82eb7c6 100644 ---- a/src/modules/module-tunnel-sink-new.c -+++ b/src/modules/module-tunnel-sink-new.c -@@ -30,6 +30,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-tunnel-source-new.c b/src/modules/module-tunnel-source-new.c -index e159c33..ff40140 100644 ---- a/src/modules/module-tunnel-source-new.c -+++ b/src/modules/module-tunnel-source-new.c -@@ -30,6 +30,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c -index d7114ee..9e5f316 100644 ---- a/src/modules/module-tunnel.c -+++ b/src/modules/module-tunnel.c -@@ -40,6 +40,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c -index bb41a96..d36b136 100644 ---- a/src/modules/module-udev-detect.c -+++ b/src/modules/module-udev-detect.c -@@ -30,6 +30,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-virtual-sink.c b/src/modules/module-virtual-sink.c -index 02cc1ac..286310e 100644 ---- a/src/modules/module-virtual-sink.c -+++ b/src/modules/module-virtual-sink.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-virtual-source.c b/src/modules/module-virtual-source.c -index 36edf78..b3403a6 100644 ---- a/src/modules/module-virtual-source.c -+++ b/src/modules/module-virtual-source.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-virtual-surround-sink.c b/src/modules/module-virtual-surround-sink.c -index 6c7120a..4d0cee5 100644 ---- a/src/modules/module-virtual-surround-sink.c -+++ b/src/modules/module-virtual-surround-sink.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/module-zeroconf-discover.c b/src/modules/module-zeroconf-discover.c -index 96476b7..e628c6b 100644 ---- a/src/modules/module-zeroconf-discover.c -+++ b/src/modules/module-zeroconf-discover.c -@@ -35,6 +35,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c -index 482881c..74018eb 100644 ---- a/src/modules/module-zeroconf-publish.c -+++ b/src/modules/module-zeroconf-publish.c -@@ -39,6 +39,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/oss/module-oss.c b/src/modules/oss/module-oss.c -index 8a5a692..a53b725 100644 ---- a/src/modules/oss/module-oss.c -+++ b/src/modules/oss/module-oss.c -@@ -51,6 +51,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/raop/module-raop-discover.c b/src/modules/raop/module-raop-discover.c -index f083044..f4ac133 100644 ---- a/src/modules/raop/module-raop-discover.c -+++ b/src/modules/raop/module-raop-discover.c -@@ -36,6 +36,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/raop/module-raop-sink.c b/src/modules/raop/module-raop-sink.c -index 7a97e83..2827b04 100644 ---- a/src/modules/raop/module-raop-sink.c -+++ b/src/modules/raop/module-raop-sink.c -@@ -41,6 +41,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c -index 864c558..bd4f90b 100644 ---- a/src/modules/raop/raop_client.c -+++ b/src/modules/raop/raop_client.c -@@ -40,6 +40,7 @@ - - #include - -+#include - #include - #include - #include -diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c -index 5977500..e77f3d0 100644 ---- a/src/modules/rtp/module-rtp-recv.c -+++ b/src/modules/rtp/module-rtp-recv.c -@@ -34,6 +34,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c -index 15a7436..ef5c526 100644 ---- a/src/modules/rtp/module-rtp-send.c -+++ b/src/modules/rtp/module-rtp-send.c -@@ -32,6 +32,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/modules/stream-interaction.c b/src/modules/stream-interaction.c -index 4184786..728398c 100644 ---- a/src/modules/stream-interaction.c -+++ b/src/modules/stream-interaction.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/modules/x11/module-x11-cork-request.c b/src/modules/x11/module-x11-cork-request.c -index 5c76711..a86a82e 100644 ---- a/src/modules/x11/module-x11-cork-request.c -+++ b/src/modules/x11/module-x11-cork-request.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - #include - - #include "module-x11-cork-request-symdef.h" -diff --git a/src/modules/x11/module-x11-xsmp.c b/src/modules/x11/module-x11-xsmp.c -index 7c6fb23..5f09d52 100644 ---- a/src/modules/x11/module-x11-xsmp.c -+++ b/src/modules/x11/module-x11-xsmp.c -@@ -31,6 +31,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c -index bc5b75b..39f4261 100644 ---- a/src/pulsecore/card.c -+++ b/src/pulsecore/card.c -@@ -30,6 +30,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c -index 9a73605..05c2b8f 100644 ---- a/src/pulsecore/cli-command.c -+++ b/src/pulsecore/cli-command.c -@@ -47,6 +47,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c -index af79a1e..9e32524 100644 ---- a/src/pulsecore/cli-text.c -+++ b/src/pulsecore/cli-text.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c -index 2e6af47..24faa1f 100644 ---- a/src/pulsecore/client.c -+++ b/src/pulsecore/client.c -@@ -29,6 +29,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c -index 026eeca..8d54720 100644 ---- a/src/pulsecore/core-scache.c -+++ b/src/pulsecore/core-scache.c -@@ -49,6 +49,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/core-struct.h b/src/pulsecore/core-struct.h -new file mode 100644 -index 0000000..e6aa374 ---- /dev/null -+++ b/src/pulsecore/core-struct.h -@@ -0,0 +1,103 @@ -+#ifndef foocorestructhfoo -+#define foocorestructhfoo -+ -+/*** -+ This file is part of PulseAudio. -+ -+ Copyright 2004-2006 Lennart Poettering -+ -+ PulseAudio 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.1 of the License, -+ or (at your option) any later version. -+ -+ PulseAudio 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 -+ General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with PulseAudio; if not, see . -+***/ -+ -+#include "core.h" -+ -+/* The core structure of PulseAudio. Every PulseAudio daemon contains -+ * exactly one of these. It is used for storing kind of global -+ * variables for the daemon. */ -+ -+struct pa_core { -+ pa_msgobject parent; -+ -+ pa_core_state_t state; -+ -+ /* A random value which may be used to identify this instance of -+ * PulseAudio. Not cryptographically secure in any way. */ -+ uint32_t cookie; -+ -+ pa_mainloop_api *mainloop; -+ -+ /* idxset of all kinds of entities */ -+ pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache; -+ -+ /* Some hashmaps for all sorts of entities */ -+ pa_hashmap *namereg, *shared; -+ -+ /* The default sink/source */ -+ pa_source *default_source; -+ pa_sink *default_sink; -+ -+ pa_channel_map default_channel_map; -+ pa_sample_spec default_sample_spec; -+ uint32_t alternate_sample_rate; -+ unsigned default_n_fragments, default_fragment_size_msec; -+ unsigned deferred_volume_safety_margin_usec; -+ int deferred_volume_extra_delay_usec; -+ unsigned lfe_crossover_freq; -+ -+ pa_defer_event *module_defer_unload_event; -+ pa_hashmap *modules_pending_unload; /* pa_module -> pa_module (hashmap-as-a-set) */ -+ -+ pa_defer_event *subscription_defer_event; -+ PA_LLIST_HEAD(pa_subscription, subscriptions); -+ PA_LLIST_HEAD(pa_subscription_event, subscription_event_queue); -+ pa_subscription_event *subscription_event_last; -+ -+ /* The mempool is used for data we write to, it's readonly for the client. */ -+ pa_mempool *mempool; -+ -+ /* Shared memory size, as specified either by daemon configuration -+ * or PA daemon defaults (~ 64 MiB). */ -+ size_t shm_size; -+ -+ pa_silence_cache silence_cache; -+ -+ pa_time_event *exit_event; -+ pa_time_event *scache_auto_unload_event; -+ -+ int exit_idle_time, scache_idle_time; -+ -+ bool flat_volumes:1; -+ bool disallow_module_loading:1; -+ bool disallow_exit:1; -+ bool running_as_daemon:1; -+ bool realtime_scheduling:1; -+ bool avoid_resampling:1; -+ bool disable_remixing:1; -+ bool remixing_use_all_sink_channels:1; -+ bool disable_lfe_remixing:1; -+ bool deferred_volume:1; -+ -+ pa_resample_method_t resample_method; -+ int realtime_priority; -+ -+ pa_server_type_t server_type; -+ pa_cpu_info cpu_info; -+ -+ /* hooks */ -+ pa_hook hooks[PA_CORE_HOOK_MAX]; -+ /* access hooks */ -+ pa_hook access[PA_ACCESS_HOOK_MAX]; -+}; -+ -+#endif /* foocorestructhfoo */ -diff --git a/src/pulsecore/core-subscribe.c b/src/pulsecore/core-subscribe.c -index 5a88b7e..88d900b 100644 ---- a/src/pulsecore/core-subscribe.c -+++ b/src/pulsecore/core-subscribe.c -@@ -28,6 +28,7 @@ - #include - #include - -+#include - #include "core-subscribe.h" - - /* The subscription subsystem may be used to be notified whenever an -diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c -index e5d6879..b8dbde9 100644 ---- a/src/pulsecore/core.c -+++ b/src/pulsecore/core.c -@@ -31,6 +31,7 @@ - #include - - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h -index 152a53f..955db89 100644 ---- a/src/pulsecore/core.h -+++ b/src/pulsecore/core.h -@@ -141,82 +141,6 @@ typedef enum pa_core_hook { - PA_CORE_HOOK_MAX - } pa_core_hook_t; - --/* The core structure of PulseAudio. Every PulseAudio daemon contains -- * exactly one of these. It is used for storing kind of global -- * variables for the daemon. */ -- --struct pa_core { -- pa_msgobject parent; -- -- pa_core_state_t state; -- -- /* A random value which may be used to identify this instance of -- * PulseAudio. Not cryptographically secure in any way. */ -- uint32_t cookie; -- -- pa_mainloop_api *mainloop; -- -- /* idxset of all kinds of entities */ -- pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache; -- -- /* Some hashmaps for all sorts of entities */ -- pa_hashmap *namereg, *shared; -- -- /* The default sink/source */ -- pa_source *default_source; -- pa_sink *default_sink; -- -- pa_channel_map default_channel_map; -- pa_sample_spec default_sample_spec; -- uint32_t alternate_sample_rate; -- unsigned default_n_fragments, default_fragment_size_msec; -- unsigned deferred_volume_safety_margin_usec; -- int deferred_volume_extra_delay_usec; -- unsigned lfe_crossover_freq; -- -- pa_defer_event *module_defer_unload_event; -- pa_hashmap *modules_pending_unload; /* pa_module -> pa_module (hashmap-as-a-set) */ -- -- pa_defer_event *subscription_defer_event; -- PA_LLIST_HEAD(pa_subscription, subscriptions); -- PA_LLIST_HEAD(pa_subscription_event, subscription_event_queue); -- pa_subscription_event *subscription_event_last; -- -- /* The mempool is used for data we write to, it's readonly for the client. */ -- pa_mempool *mempool; -- -- /* Shared memory size, as specified either by daemon configuration -- * or PA daemon defaults (~ 64 MiB). */ -- size_t shm_size; -- -- pa_silence_cache silence_cache; -- -- pa_time_event *exit_event; -- pa_time_event *scache_auto_unload_event; -- -- int exit_idle_time, scache_idle_time; -- -- bool flat_volumes:1; -- bool disallow_module_loading:1; -- bool disallow_exit:1; -- bool running_as_daemon:1; -- bool realtime_scheduling:1; -- bool disable_remixing:1; -- bool disable_lfe_remixing:1; -- bool deferred_volume:1; -- -- pa_resample_method_t resample_method; -- int realtime_priority; -- -- pa_server_type_t server_type; -- pa_cpu_info cpu_info; -- -- /* hooks */ -- pa_hook hooks[PA_CORE_HOOK_MAX]; -- /* access hooks */ -- pa_hook access[PA_ACCESS_HOOK_MAX]; --}; -- - PA_DECLARE_PUBLIC_CLASS(pa_core); - #define PA_CORE(o) pa_core_cast(o) - -diff --git a/src/pulsecore/dbus-shared.c b/src/pulsecore/dbus-shared.c -index 935b068..3309f87 100644 ---- a/src/pulsecore/dbus-shared.c -+++ b/src/pulsecore/dbus-shared.c -@@ -24,6 +24,7 @@ - - #include - -+#include - #include - - #include "dbus-shared.h" -diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c -index 7c9ddf3..bc4d704 100644 ---- a/src/pulsecore/device-port.c -+++ b/src/pulsecore/device-port.c -@@ -21,6 +21,7 @@ - - #include "device-port.h" - #include -+#include - #include - - PA_DEFINE_PUBLIC_CLASS(pa_device_port, pa_object); -diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c -index ac15815..da2abe0 100644 ---- a/src/pulsecore/module.c -+++ b/src/pulsecore/module.c -@@ -31,6 +31,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c -index 47bfc08..dfdcc43 100644 ---- a/src/pulsecore/namereg.c -+++ b/src/pulsecore/namereg.c -@@ -30,6 +30,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c -index cc0bc16..3c7e5a6 100644 ---- a/src/pulsecore/play-memchunk.c -+++ b/src/pulsecore/play-memchunk.c -@@ -24,6 +24,7 @@ - #include - #include - -+#include - #include - #include - -diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c -index 4f83ac4..ead1d81 100644 ---- a/src/pulsecore/protocol-esound.c -+++ b/src/pulsecore/protocol-esound.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/protocol-http.c b/src/pulsecore/protocol-http.c -index 25a2cd0..bbb03c3 100644 ---- a/src/pulsecore/protocol-http.c -+++ b/src/pulsecore/protocol-http.c -@@ -30,6 +30,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c -index 8f07b2d..cbb6ae6 100644 ---- a/src/pulsecore/protocol-native.c -+++ b/src/pulsecore/protocol-native.c -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c -index 923ec87..bd9136b 100644 ---- a/src/pulsecore/protocol-simple.c -+++ b/src/pulsecore/protocol-simple.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/shared.c b/src/pulsecore/shared.c -index 1b5eea9..2e63d0e 100644 ---- a/src/pulsecore/shared.c -+++ b/src/pulsecore/shared.c -@@ -22,6 +22,7 @@ - #endif - - #include -+#include - #include - - #include "shared.h" -diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c -index e9694f2..9a866b4 100644 ---- a/src/pulsecore/sink-input.c -+++ b/src/pulsecore/sink-input.c -@@ -30,6 +30,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c -index aa21822..20249ec 100644 ---- a/src/pulsecore/sink.c -+++ b/src/pulsecore/sink.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c -index ddda456..3ac935d 100644 ---- a/src/pulsecore/sound-file-stream.c -+++ b/src/pulsecore/sound-file-stream.c -@@ -32,6 +32,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c -index 6714ea9..a265e6f 100644 ---- a/src/pulsecore/source-output.c -+++ b/src/pulsecore/source-output.c -@@ -30,6 +30,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c -index 8ce7818..7a33d5b 100644 ---- a/src/pulsecore/source.c -+++ b/src/pulsecore/source.c -@@ -33,6 +33,7 @@ - #include - #include - -+#include - #include - #include - #include -diff --git a/src/pulsecore/x11wrap.c b/src/pulsecore/x11wrap.c -index 0c040cf..76cb83b 100644 ---- a/src/pulsecore/x11wrap.c -+++ b/src/pulsecore/x11wrap.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include - #include - --- -2.9.3 - diff --git a/0010-Don-t-access-pa_core-structures-directly.patch b/0010-Don-t-access-pa_core-structures-directly.patch deleted file mode 100644 index 9bc94a5..0000000 --- a/0010-Don-t-access-pa_core-structures-directly.patch +++ /dev/null @@ -1,1639 +0,0 @@ -From 420e714464f6ab6f943de7ef99b92b5d3f4814e2 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Tue, 7 Apr 2015 16:53:09 +0200 -Subject: [PATCH 10/18] Don't access pa_core structures directly - -First step to allowing access control. Make sure we only use the -methods to get core datastructures so that we can do access control -later. ---- - src/pulsecore/cli-command.c | 72 ++++++++++++-------- - src/pulsecore/cli-text.c | 85 ++++++++++++++++------- - src/pulsecore/core.c | 102 ++++++++++++++++++++++++++++ - src/pulsecore/core.h | 30 ++++++++ - src/pulsecore/namereg.c | 35 +++++++--- - src/pulsecore/protocol-esound.c | 29 ++++---- - src/pulsecore/protocol-http.c | 12 +++- - src/pulsecore/protocol-native.c | 147 ++++++++++++++++++++++------------------ - src/pulsecore/protocol-simple.c | 5 +- - src/pulsecore/sink.c | 6 +- - src/pulsecore/source.c | 6 +- - 11 files changed, 380 insertions(+), 149 deletions(-) - -diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c -index 05c2b8f..138881c 100644 ---- a/src/pulsecore/cli-command.c -+++ b/src/pulsecore/cli-command.c -@@ -47,7 +47,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -362,7 +361,7 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - pa_assert(buf); - pa_assert(fail); - -- mstat = pa_mempool_get_stat(c->mempool); -+ mstat = pa_mempool_get_stat(pa_core_get_mempool(c)); - - pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n", - (unsigned) pa_atomic_load(&mstat->n_allocated), -@@ -384,10 +383,10 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_scache_total_size(c))); - - pa_strbuf_printf(buf, "Default sample spec: %s\n", -- pa_sample_spec_snprint(ss, sizeof(ss), &c->default_sample_spec)); -+ pa_sample_spec_snprint(ss, sizeof(ss), pa_core_get_sample_spec(c))); - - pa_strbuf_printf(buf, "Default channel map: %s\n", -- pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map)); -+ pa_channel_map_snprint(cm, sizeof(cm), pa_core_get_channel_map(c))); - - def_sink = pa_namereg_get_default_sink(c); - def_source = pa_namereg_get_default_source(c); -@@ -437,7 +436,7 @@ static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - return -1; - } - -- if (!pa_module_load(c, name, pa_tokenizer_get(t, 2))) { -+ if (!pa_module_load(c, name, pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "Module load failed.\n"); - return -1; - } -@@ -462,7 +461,7 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bo - } - - if (pa_atou(i, &idx) >= 0) { -- if (!(m = pa_idxset_get_by_index(c->modules, idx))) { -+ if (!(m = pa_core_get_module(c, idx))) { - pa_strbuf_puts(buf, "Invalid module index.\n"); - return -1; - } -@@ -470,12 +469,15 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bo - pa_module_unload_request(m, false); - - } else { -- PA_IDXSET_FOREACH(m, c->modules, idx) -+ pa_idxset *modules = pa_core_get_modules(c); -+ PA_IDXSET_FOREACH(m, modules, idx) - if (pa_streq(i, m->name)) { - unloaded = true; - pa_module_unload_request(m, false); - } - -+ pa_idxset_free(modules, NULL); -+ - if (unloaded == false) { - pa_strbuf_printf(buf, "Module %s not loaded.\n", i); - return -1; -@@ -604,7 +606,7 @@ static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strb - return -1; - } - -- if (!(si = pa_idxset_get_by_index(c->sink_inputs, idx))) { -+ if (!(si = pa_core_get_sink_input(c, idx))) { - pa_strbuf_puts(buf, "No sink input found with this index.\n"); - return -1; - } -@@ -697,7 +699,7 @@ static int pa_cli_command_source_output_volume(pa_core *c, pa_tokenizer *t, pa_s - return -1; - } - -- if (!(so = pa_idxset_get_by_index(c->source_outputs, idx))) { -+ if (!(so = pa_core_get_source_output(c, idx))) { - pa_strbuf_puts(buf, "No source output found with this index.\n"); - return -1; - } -@@ -880,7 +882,7 @@ static int pa_cli_command_update_sink_input_proplist(pa_core *c, pa_tokenizer *t - return -1; - } - -- if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) { -+ if (!(si = pa_core_get_sink_input(c, (uint32_t) idx))) { - pa_strbuf_puts(buf, "No sink input found with this index.\n"); - return -1; - } -@@ -923,7 +925,7 @@ static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer - return -1; - } - -- if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) { -+ if (!(so = pa_core_get_source_output(c, (uint32_t) idx))) { - pa_strbuf_puts(buf, "No source output found with this index.\n"); - return -1; - } -@@ -971,7 +973,7 @@ static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf - return -1; - } - -- if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) { -+ if (!(si = pa_core_get_sink_input(c, (uint32_t) idx))) { - pa_strbuf_puts(buf, "No sink input found with this index.\n"); - return -1; - } -@@ -1011,7 +1013,7 @@ static int pa_cli_command_source_output_mute(pa_core *c, pa_tokenizer *t, pa_str - return -1; - } - -- if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) { -+ if (!(so = pa_core_get_source_output(c, (uint32_t) idx))) { - pa_strbuf_puts(buf, "No source output found with this index.\n"); - return -1; - } -@@ -1065,7 +1067,7 @@ static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf - - static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool *fail) { - const char *n; -- pa_client *client; -+ pa_client *cl; - uint32_t idx; - - pa_core_assert_ref(c); -@@ -1083,12 +1085,12 @@ static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *bu - return -1; - } - -- if (!(client = pa_idxset_get_by_index(c->clients, idx))) { -+ if (!(cl = pa_core_get_client(c, idx))) { - pa_strbuf_puts(buf, "No client found by this index.\n"); - return -1; - } - -- pa_client_kill(client); -+ pa_client_kill(cl); - return 0; - } - -@@ -1112,7 +1114,7 @@ static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf - return -1; - } - -- if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx))) { -+ if (!(sink_input = pa_core_get_sink_input(c, idx))) { - pa_strbuf_puts(buf, "No sink input found by this index.\n"); - return -1; - } -@@ -1141,7 +1143,7 @@ static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_str - return -1; - } - -- if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx))) { -+ if (!(source_output = pa_core_get_source_output(c, idx))) { - pa_strbuf_puts(buf, "No source output found by this index.\n"); - return -1; - } -@@ -1300,7 +1302,7 @@ static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bo - pa_assert(buf); - pa_assert(fail); - -- pa_mempool_vacuum(c->mempool); -+ pa_mempool_vacuum(pa_core_get_mempool(c)); - - return 0; - } -@@ -1331,7 +1333,7 @@ static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf - return -1; - } - -- if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) { -+ if (!(si = pa_core_get_sink_input(c, (uint32_t) idx))) { - pa_strbuf_puts(buf, "No sink input found with this index.\n"); - return -1; - } -@@ -1374,7 +1376,7 @@ static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_str - return -1; - } - -- if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) { -+ if (!(so = pa_core_get_source_output(c, (uint32_t) idx))) { - pa_strbuf_puts(buf, "No source output found with this index.\n"); - return -1; - } -@@ -1789,6 +1791,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - #ifdef HAVE_CTIME_R - char txt[256]; - #endif -+ pa_idxset *i; - - pa_core_assert_ref(c); - pa_assert(t); -@@ -1802,8 +1805,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - #else - pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now)); - #endif -- -- PA_IDXSET_FOREACH(m, c->modules, idx) { -+ i = pa_core_get_modules(c); -+ PA_IDXSET_FOREACH(m, i, idx) { - - pa_strbuf_printf(buf, "load-module %s", m->name); - -@@ -1812,9 +1815,11 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - - pa_strbuf_puts(buf, "\n"); - } -+ pa_idxset_free(i, NULL); - - nl = false; -- PA_IDXSET_FOREACH(sink, c->sinks, idx) { -+ i = pa_core_get_sinks(c); -+ PA_IDXSET_FOREACH(sink, i, idx) { - - if (!nl) { - pa_strbuf_puts(buf, "\n"); -@@ -1825,9 +1830,11 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, false))); - pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED)); - } -+ pa_idxset_free(i, NULL); - - nl = false; -- PA_IDXSET_FOREACH(source, c->sources, idx) { -+ i = pa_core_get_sources(c); -+ PA_IDXSET_FOREACH(source, i, idx) { - - if (!nl) { - pa_strbuf_puts(buf, "\n"); -@@ -1838,9 +1845,11 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, false))); - pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED)); - } -+ pa_idxset_free(i, NULL); - - nl = false; -- PA_IDXSET_FOREACH(card, c->cards, idx) { -+ i = pa_core_get_cards(c); -+ PA_IDXSET_FOREACH(card, i, idx) { - - if (!nl) { - pa_strbuf_puts(buf, "\n"); -@@ -1849,6 +1858,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, bool - - pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name); - } -+ pa_idxset_free(i, NULL); - - nl = false; - if ((sink = pa_namereg_get_default_sink(c))) { -@@ -1880,13 +1890,16 @@ static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *b - uint32_t s_idx, i_idx; - char v_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX]; - pa_channel_map *map; -+ pa_idxset *sinks, *sources; - - pa_core_assert_ref(c); - pa_assert(t); - pa_assert(buf); - pa_assert(fail); - -- PA_IDXSET_FOREACH(s, c->sinks, s_idx) { -+ sinks = pa_core_get_sinks(c); -+ -+ PA_IDXSET_FOREACH(s, sinks, s_idx) { - map = &s->channel_map; - pa_strbuf_printf(buf, "Sink %d: ", s_idx); - pa_strbuf_printf(buf, -@@ -1937,8 +1950,10 @@ static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *b - pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(i->save_volume)); - } - } -+ pa_idxset_free(sinks, NULL); - -- PA_IDXSET_FOREACH(so, c->sources, s_idx) { -+ sources = pa_core_get_sources(c); -+ PA_IDXSET_FOREACH(so, sources, s_idx) { - map = &so->channel_map; - pa_strbuf_printf(buf, "Source %d: ", s_idx); - pa_strbuf_printf(buf, -@@ -1989,6 +2004,7 @@ static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *b - pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(o->save_volume)); - } - } -+ pa_idxset_free(sources, NULL); - - return 0; - } -diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c -index 9e32524..239ab5d 100644 ---- a/src/pulsecore/cli-text.c -+++ b/src/pulsecore/cli-text.c -@@ -32,7 +32,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -44,13 +43,17 @@ char *pa_module_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_module *m; - uint32_t idx = PA_IDXSET_INVALID; -+ pa_idxset *modules; -+ - pa_assert(c); - - s = pa_strbuf_new(); - -- pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(c->modules)); -+ modules = pa_core_get_modules(c); -+ -+ pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(modules)); - -- PA_IDXSET_FOREACH(m, c->modules, idx) { -+ PA_IDXSET_FOREACH(m, modules, idx) { - char *t; - - pa_strbuf_printf(s, " index: %u\n" -@@ -68,36 +71,42 @@ char *pa_module_list_to_string(pa_core *c) { - pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); - pa_xfree(t); - } -+ pa_idxset_free(modules, NULL); - - return pa_strbuf_to_string_free(s); - } - - char *pa_client_list_to_string(pa_core *c) { - pa_strbuf *s; -- pa_client *client; -+ pa_client *cl; - uint32_t idx = PA_IDXSET_INVALID; -+ pa_idxset *clients; -+ - pa_assert(c); - - s = pa_strbuf_new(); - -- pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(c->clients)); -+ clients = pa_core_get_clients(c); -+ -+ pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(clients)); - -- PA_IDXSET_FOREACH(client, c->clients, idx) { -+ PA_IDXSET_FOREACH(cl, clients, idx) { - char *t; - pa_strbuf_printf( - s, - " index: %u\n" - "\tdriver: <%s>\n", -- client->index, -- client->driver); -+ cl->index, -+ cl->driver); - -- if (client->module) -- pa_strbuf_printf(s, "\towner module: %u\n", client->module->index); -+ if (cl->module) -+ pa_strbuf_printf(s, "\towner module: %u\n", cl->module->index); - -- t = pa_proplist_to_string_sep(client->proplist, "\n\t\t"); -+ t = pa_proplist_to_string_sep(cl->proplist, "\n\t\t"); - pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); - pa_xfree(t); - } -+ pa_idxset_free(clients, NULL); - - return pa_strbuf_to_string_free(s); - } -@@ -139,13 +148,17 @@ char *pa_card_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_card *card; - uint32_t idx = PA_IDXSET_INVALID; -+ pa_idxset *cards; -+ - pa_assert(c); - - s = pa_strbuf_new(); - -- pa_strbuf_printf(s, "%u card(s) available.\n", pa_idxset_size(c->cards)); -+ cards = pa_core_get_cards(c); -+ -+ pa_strbuf_printf(s, "%u card(s) available.\n", pa_idxset_size(cards)); - -- PA_IDXSET_FOREACH(card, c->cards, idx) { -+ PA_IDXSET_FOREACH(card, cards, idx) { - char *t; - pa_sink *sink; - pa_source *source; -@@ -193,6 +206,7 @@ char *pa_card_list_to_string(pa_core *c) { - - append_port_list(s, card->ports); - } -+ pa_idxset_free(cards, NULL); - - return pa_strbuf_to_string_free(s); - } -@@ -235,15 +249,19 @@ char *pa_sink_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_sink *sink, *default_sink; - uint32_t idx = PA_IDXSET_INVALID; -+ pa_idxset *sinks; -+ - pa_assert(c); - - s = pa_strbuf_new(); - -- pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks)); -+ sinks = pa_core_get_sinks(c); -+ -+ pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(sinks)); - - default_sink = pa_namereg_get_default_sink(c); - -- PA_IDXSET_FOREACH(sink, c->sinks, idx) { -+ PA_IDXSET_FOREACH(sink, sinks, idx) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], - cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX], - v[PA_VOLUME_SNPRINT_VERBOSE_MAX], -@@ -345,6 +363,7 @@ char *pa_sink_list_to_string(pa_core *c) { - "\tactive port: <%s>\n", - sink->active_port->name); - } -+ pa_idxset_free(sinks, NULL); - - return pa_strbuf_to_string_free(s); - } -@@ -353,15 +372,19 @@ char *pa_source_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_source *source, *default_source; - uint32_t idx = PA_IDXSET_INVALID; -+ pa_idxset *sources; -+ - pa_assert(c); - - s = pa_strbuf_new(); - -- pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources)); -+ sources = pa_core_get_sources(c); -+ -+ pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(sources)); - - default_source = pa_namereg_get_default_source(c); - -- PA_IDXSET_FOREACH(source, c->sources, idx) { -+ PA_IDXSET_FOREACH(source, sources, idx) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], - cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX], - v[PA_VOLUME_SNPRINT_VERBOSE_MAX], -@@ -460,6 +483,7 @@ char *pa_source_list_to_string(pa_core *c) { - "\tactive port: <%s>\n", - source->active_port->name); - } -+ pa_idxset_free(sources, NULL); - - return pa_strbuf_to_string_free(s); - } -@@ -474,13 +498,16 @@ char *pa_source_output_list_to_string(pa_core *c) { - [PA_SOURCE_OUTPUT_CORKED] = "CORKED", - [PA_SOURCE_OUTPUT_UNLINKED] = "UNLINKED" - }; -+ pa_idxset *source_outputs; - pa_assert(c); - - s = pa_strbuf_new(); - -- pa_strbuf_printf(s, "%u source output(s) available.\n", pa_idxset_size(c->source_outputs)); -+ source_outputs = pa_core_get_source_outputs(c); -+ -+ pa_strbuf_printf(s, "%u source output(s) available.\n", pa_idxset_size(source_outputs)); - -- PA_IDXSET_FOREACH(o, c->source_outputs, idx) { -+ PA_IDXSET_FOREACH(o, source_outputs, idx) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], *t, clt[28]; - pa_usec_t cl; - const char *cmn; -@@ -557,6 +584,7 @@ char *pa_source_output_list_to_string(pa_core *c) { - pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); - pa_xfree(t); - } -+ pa_idxset_free(source_outputs, NULL); - - return pa_strbuf_to_string_free(s); - } -@@ -572,13 +600,16 @@ char *pa_sink_input_list_to_string(pa_core *c) { - [PA_SINK_INPUT_CORKED] = "CORKED", - [PA_SINK_INPUT_UNLINKED] = "UNLINKED" - }; -+ pa_idxset *sink_inputs; - - pa_assert(c); - s = pa_strbuf_new(); - -- pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(c->sink_inputs)); -+ sink_inputs = pa_core_get_sink_inputs(c); - -- PA_IDXSET_FOREACH(i, c->sink_inputs, idx) { -+ pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(sink_inputs)); -+ -+ PA_IDXSET_FOREACH(i, sink_inputs, idx) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], *t, clt[28]; - pa_usec_t cl; - const char *cmn; -@@ -653,23 +684,28 @@ char *pa_sink_input_list_to_string(pa_core *c) { - pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); - pa_xfree(t); - } -+ pa_idxset_free(sink_inputs, NULL); - - return pa_strbuf_to_string_free(s); - } - - char *pa_scache_list_to_string(pa_core *c) { - pa_strbuf *s; -+ pa_idxset *scache; -+ - pa_assert(c); - - s = pa_strbuf_new(); - -- pa_strbuf_printf(s, "%u cache entrie(s) available.\n", c->scache ? pa_idxset_size(c->scache) : 0); -+ scache = pa_core_get_scache(c); -+ -+ pa_strbuf_printf(s, "%u cache entrie(s) available.\n", scache ? pa_idxset_size(scache) : 0); - -- if (c->scache) { -+ if (scache) { - pa_scache_entry *e; - uint32_t idx = PA_IDXSET_INVALID; - -- PA_IDXSET_FOREACH(e, c->scache, idx) { -+ PA_IDXSET_FOREACH(e, scache, idx) { - double l = 0; - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX] = "n/a", cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX] = "n/a", *t; - const char *cmn; -@@ -711,6 +747,7 @@ char *pa_scache_list_to_string(pa_core *c) { - pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); - pa_xfree(t); - } -+ pa_idxset_free(scache, NULL); - } - - return pa_strbuf_to_string_free(s); -diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c -index b8dbde9..b068f5d 100644 ---- a/src/pulsecore/core.c -+++ b/src/pulsecore/core.c -@@ -262,6 +262,11 @@ int pa_core_exit(pa_core *c, bool force, int retval) { - return 0; - } - -+pa_hook_result_t pa_core_hook_fire(pa_core *c, pa_core_hook_t hook, void *data) { -+ pa_assert(c); -+ return pa_hook_fire(&c->hooks[hook], data); -+} -+ - void pa_core_maybe_vacuum(pa_core *c) { - pa_assert(c); - -@@ -305,3 +310,100 @@ void pa_core_rttime_restart(pa_core *c, pa_time_event *e, pa_usec_t usec) { - - c->mainloop->time_restart(e, pa_timeval_rtstore(&tv, usec, true)); - } -+ -+pa_mainloop_api* pa_core_get_mainloop(pa_core *c) { -+ pa_assert(c); -+ pa_assert(c->mainloop); -+ -+ return c->mainloop; -+} -+ -+/* FIXME: Should we expose this at all? */ -+pa_mempool* pa_core_get_mempool(pa_core *c) { -+ pa_assert(c); -+ pa_assert(c->mempool); -+ -+ return c->mempool; -+} -+ -+pa_mempool* pa_core_new_mempool(pa_core *c, pa_mem_type_t shm_type, bool per_client) { -+ return pa_mempool_new(shm_type, c->shm_size, per_client); -+} -+ -+/* FIXME: Should these be taking a ref during the copy? */ -+ -+pa_idxset* pa_core_get_modules(pa_core *c) { -+ return pa_idxset_copy(c->modules, NULL); -+} -+ -+pa_idxset* pa_core_get_clients(pa_core *c) { -+ return pa_idxset_copy(c->clients, NULL); -+} -+ -+pa_idxset* pa_core_get_cards(pa_core *c) { -+ return pa_idxset_copy(c->cards, NULL); -+} -+ -+pa_idxset* pa_core_get_sinks(pa_core *c) { -+ return pa_idxset_copy(c->sinks, NULL); -+} -+ -+pa_idxset* pa_core_get_sources(pa_core *c) { -+ return pa_idxset_copy(c->sources, NULL); -+} -+ -+pa_idxset* pa_core_get_sink_inputs(pa_core *c) { -+ return pa_idxset_copy(c->sink_inputs, NULL); -+} -+ -+pa_idxset* pa_core_get_source_outputs(pa_core *c) { -+ return pa_idxset_copy(c->source_outputs, NULL); -+} -+ -+pa_idxset* pa_core_get_scache(pa_core *c) { -+ return pa_idxset_copy(c->scache, NULL); -+} -+ -+pa_module* pa_core_get_module(pa_core *c, uint32_t idx) { -+ return pa_idxset_get_by_index(c->modules, idx); -+} -+ -+pa_client* pa_core_get_client(pa_core *c, uint32_t idx) { -+ return pa_idxset_get_by_index(c->clients, idx); -+} -+ -+pa_card* pa_core_get_card(pa_core *c, uint32_t idx) { -+ return pa_idxset_get_by_index(c->cards, idx); -+} -+ -+pa_sink* pa_core_get_sink(pa_core *c, uint32_t idx) { -+ return pa_idxset_get_by_index(c->sinks, idx); -+} -+ -+pa_source* pa_core_get_source(pa_core *c, uint32_t idx) { -+ return pa_idxset_get_by_index(c->sources, idx); -+} -+ -+pa_sink_input* pa_core_get_sink_input(pa_core *c, uint32_t idx) { -+ return pa_idxset_get_by_index(c->sink_inputs, idx); -+} -+ -+pa_source_output* pa_core_get_source_output(pa_core *c, uint32_t idx) { -+ return pa_idxset_get_by_index(c->source_outputs, idx); -+} -+ -+pa_scache_entry* pa_core_get_scache_entry(pa_core *c, uint32_t idx) { -+ return pa_idxset_get_by_index(c->scache, idx); -+} -+ -+const pa_sample_spec* pa_core_get_sample_spec(pa_core *c) { -+ return &c->default_sample_spec; -+} -+ -+const pa_channel_map* pa_core_get_channel_map(pa_core *c) { -+ return &c->default_channel_map; -+} -+ -+uint32_t pa_core_get_cookie(pa_core *c) { -+ return c->cookie; -+} -diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h -index 955db89..87b055d 100644 ---- a/src/pulsecore/core.h -+++ b/src/pulsecore/core.h -@@ -158,8 +158,38 @@ int pa_core_exit(pa_core *c, bool force, int retval); - - void pa_core_maybe_vacuum(pa_core *c); - -+pa_hook_result_t pa_core_hook_fire(pa_core *c, pa_core_hook_t hook, void *data); -+ - /* wrapper for c->mainloop->time_*() RT time events */ - pa_time_event* pa_core_rttime_new(pa_core *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata); - void pa_core_rttime_restart(pa_core *c, pa_time_event *e, pa_usec_t usec); - -+pa_mainloop_api* pa_core_get_mainloop(pa_core *c); -+pa_mempool* pa_core_get_mempool(pa_core *c); -+pa_mempool* pa_core_new_mempool(pa_core *c, pa_mem_type_t shm_type, bool per_client); -+ -+pa_idxset* pa_core_get_modules(pa_core *c); -+pa_idxset* pa_core_get_clients(pa_core *c); -+pa_idxset* pa_core_get_cards(pa_core *c); -+pa_idxset* pa_core_get_sinks(pa_core *c); -+pa_idxset* pa_core_get_sources(pa_core *c); -+pa_idxset* pa_core_get_sink_inputs(pa_core *c); -+pa_idxset* pa_core_get_source_outputs(pa_core *c); -+pa_idxset* pa_core_get_scache(pa_core *c); -+ -+pa_module* pa_core_get_module(pa_core *c, uint32_t idx); -+pa_client* pa_core_get_client(pa_core *c, uint32_t idx); -+pa_card* pa_core_get_card(pa_core *c, uint32_t idx); -+pa_sink* pa_core_get_sink(pa_core *c, uint32_t idx); -+pa_source* pa_core_get_source(pa_core *c, uint32_t idx); -+pa_sink_input* pa_core_get_sink_input(pa_core *c, uint32_t idx); -+pa_source_output* pa_core_get_source_output(pa_core *c, uint32_t idx); -+typedef struct pa_scache_entry pa_scache_entry; -+pa_scache_entry* pa_core_get_scache_entry(pa_core *c, uint32_t idx); -+ -+const pa_sample_spec* pa_core_get_sample_spec(pa_core *c); -+const pa_channel_map* pa_core_get_channel_map(pa_core *c); -+ -+uint32_t pa_core_get_cookie(pa_core *c); -+ - #endif -diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c -index dfdcc43..699fa1b 100644 ---- a/src/pulsecore/namereg.c -+++ b/src/pulsecore/namereg.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -239,13 +240,13 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) { - return NULL; - - if (type == PA_NAMEREG_SINK) -- return pa_idxset_get_by_index(c->sinks, idx); -+ return pa_core_get_sink(c, idx); - else if (type == PA_NAMEREG_SOURCE) -- return pa_idxset_get_by_index(c->sources, idx); -- else if (type == PA_NAMEREG_SAMPLE && c->scache) -- return pa_idxset_get_by_index(c->scache, idx); -+ return pa_core_get_source(c, idx); -+ else if (type == PA_NAMEREG_SAMPLE) -+ return pa_core_get_scache_entry(c, idx); - else if (type == PA_NAMEREG_CARD) -- return pa_idxset_get_by_index(c->cards, idx); -+ return pa_core_get_card(c, idx); - - return NULL; - } -@@ -258,7 +259,7 @@ pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) { - - if (c->default_sink != s) { - c->default_sink = s; -- pa_hook_fire(&c->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], c->default_sink); -+ pa_core_hook_fire(c, PA_CORE_HOOK_DEFAULT_SINK_CHANGED, c->default_sink); - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); - } - -@@ -273,7 +274,7 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) { - - if (c->default_source != s) { - c->default_source = s; -- pa_hook_fire(&c->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], c->default_source); -+ pa_core_hook_fire(c, PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED, c->default_source); - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); - } - -@@ -283,41 +284,50 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) { - pa_sink *pa_namereg_get_default_sink(pa_core *c) { - pa_sink *s, *best = NULL; - uint32_t idx; -+ pa_idxset *sinks; - - pa_assert(c); - - if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink))) - return c->default_sink; - -- PA_IDXSET_FOREACH(s, c->sinks, idx) -+ sinks = pa_core_get_sinks(c); -+ -+ PA_IDXSET_FOREACH(s, sinks, idx) - if (PA_SINK_IS_LINKED(pa_sink_get_state(s))) - if (!best || s->priority > best->priority) - best = s; - -+ pa_idxset_free(sinks, NULL); -+ - return best; - } - - pa_source *pa_namereg_get_default_source(pa_core *c) { - pa_source *s, *best = NULL; - uint32_t idx; -+ pa_idxset *sources; - - pa_assert(c); - - if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source))) - return c->default_source; - -+ sources = pa_core_get_sources(c); -+ - /* First, try to find one that isn't a monitor */ -- PA_IDXSET_FOREACH(s, c->sources, idx) -+ PA_IDXSET_FOREACH(s, sources, idx) - if (!s->monitor_of && PA_SOURCE_IS_LINKED(pa_source_get_state(s))) - if (!best || - s->priority > best->priority) - best = s; - -+ - if (best) -- return best; -+ goto done; - - /* Then, fallback to a monitor */ -- PA_IDXSET_FOREACH(s, c->sources, idx) -+ PA_IDXSET_FOREACH(s, sources, idx) - if (PA_SOURCE_IS_LINKED(pa_source_get_state(s))) - if (!best || - s->priority > best->priority || -@@ -327,5 +337,8 @@ pa_source *pa_namereg_get_default_source(pa_core *c) { - s->monitor_of->priority > best->monitor_of->priority)) - best = s; - -+done: -+ pa_idxset_free(sources, NULL); -+ - return best; - } -diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c -index ead1d81..0d76525 100644 ---- a/src/pulsecore/protocol-esound.c -+++ b/src/pulsecore/protocol-esound.c -@@ -41,7 +41,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -240,12 +239,12 @@ static void connection_unlink(connection *c) { - } - - if (c->defer_event) { -- c->protocol->core->mainloop->defer_free(c->defer_event); -+ pa_core_get_mainloop (c->protocol->core)->defer_free(c->defer_event); - c->defer_event = NULL; - } - - if (c->auth_timeout_event) { -- c->protocol->core->mainloop->time_free(c->auth_timeout_event); -+ pa_core_get_mainloop (c->protocol->core)->time_free(c->auth_timeout_event); - c->auth_timeout_event = NULL; - } - -@@ -293,7 +292,7 @@ static void connection_write(connection *c, const void *data, size_t length) { - size_t i; - pa_assert(c); - -- c->protocol->core->mainloop->defer_enable(c->defer_event, 1); -+ pa_core_get_mainloop (c->protocol->core)->defer_enable(c->defer_event, 1); - - connection_write_prepare(c, length); - -@@ -355,7 +354,7 @@ static int esd_proto_connect(connection *c, esd_proto_t request, const void *dat - } - - if (c->auth_timeout_event) { -- c->protocol->core->mainloop->time_free(c->auth_timeout_event); -+ pa_core_get_mainloop (c->protocol->core)->time_free(c->auth_timeout_event); - c->auth_timeout_event = NULL; - } - -@@ -614,6 +613,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da - uint32_t idx = PA_IDXSET_INVALID; - unsigned nsamples; - char terminator[sizeof(int32_t)*6+ESD_NAME_MAX]; -+ pa_idxset *scache; - - connection_assert_ref(c); - pa_assert(data); -@@ -624,7 +624,8 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da - - k = sizeof(int32_t)*5+ESD_NAME_MAX; - s = sizeof(int32_t)*6+ESD_NAME_MAX; -- nsamples = pa_idxset_size(c->protocol->core->scache); -+ scache = pa_core_get_scache(c->protocol->core); -+ nsamples = pa_idxset_size(scache); - t = s*(nsamples+1) + k*(c->protocol->n_player+1); - - connection_write_prepare(c, t); -@@ -690,7 +691,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da - - idx = PA_IDXSET_INVALID; - -- PA_IDXSET_FOREACH(ce, c->protocol->core->scache, idx) { -+ PA_IDXSET_FOREACH(ce, scache, idx) { - int32_t id, rate, lvolume, rvolume, format, len; - char name[ESD_NAME_MAX]; - pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } }; -@@ -748,6 +749,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da - t -= s; - } - } -+ pa_idxset_free(scache, NULL); - - pa_assert(t == s); - -@@ -817,7 +819,7 @@ static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void * - volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE; - volume.channels = 2; - -- if ((ce = pa_idxset_get_by_index(c->protocol->core->scache, idx))) { -+ if ((ce = pa_core_get_scache_entry(c->protocol->core, idx))) { - pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } }; - - pa_cvolume_remap(&volume, &stereo, &ce->channel_map); -@@ -866,7 +868,7 @@ static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void - CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name."); - - pa_assert(!c->scache.memchunk.memblock); -- c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) sc_length); -+ c->scache.memchunk.memblock = pa_memblock_new(pa_core_get_mempool (c->protocol->core), (size_t) sc_length); - c->scache.memchunk.index = 0; - c->scache.memchunk.length = (size_t) sc_length; - c->scache.sample_spec = ss; -@@ -1150,7 +1152,7 @@ static int do_read(connection *c) { - } - - if (!c->playback.current_memblock) { -- pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) -1)); -+ pa_assert_se(c->playback.current_memblock = pa_memblock_new(pa_core_get_mempool(c->protocol->core), (size_t) -1)); - c->playback.memblock_index = 0; - - space = pa_memblock_get_length(c->playback.current_memblock); -@@ -1237,7 +1239,7 @@ static int do_write(connection *c) { - static void do_work(connection *c) { - connection_assert_ref(c); - -- c->protocol->core->mainloop->defer_enable(c->defer_event, 0); -+ pa_core_get_mainloop(c->protocol->core)->defer_enable(c->defer_event, 0); - - if (c->dead) - return; -@@ -1273,6 +1275,7 @@ fail: - pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, 0, NULL, NULL); - } else - connection_unlink(c); -+ - } - - static void io_callback(pa_iochannel*io, void *userdata) { -@@ -1562,8 +1565,8 @@ void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esou - else - c->auth_timeout_event = NULL; - -- c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c); -- p->core->mainloop->defer_enable(c->defer_event, 0); -+ c->defer_event = pa_core_get_mainloop(p->core)->defer_new(pa_core_get_mainloop(p->core), defer_callback, c); -+ pa_core_get_mainloop(p->core)->defer_enable(c->defer_event, 0); - - pa_idxset_put(p->connections, c, &c->index); - } -diff --git a/src/pulsecore/protocol-http.c b/src/pulsecore/protocol-http.c -index bbb03c3..64024df 100644 ---- a/src/pulsecore/protocol-http.c -+++ b/src/pulsecore/protocol-http.c -@@ -30,7 +30,6 @@ - #include - #include - --#include - #include - #include - #include -@@ -458,6 +457,7 @@ static void handle_listen(struct connection *c) { - pa_source *source; - pa_sink *sink; - uint32_t idx; -+ pa_idxset *sinks, *sources; - - http_response(c, 200, "OK", MIME_HTML); - -@@ -471,7 +471,9 @@ static void handle_listen(struct connection *c) { - return; - } - -- PA_IDXSET_FOREACH(sink, c->protocol->core->sinks, idx) { -+ sinks = pa_core_get_sinks(c->protocol->core); -+ -+ PA_IDXSET_FOREACH(sink, sinks, idx) { - char *t, *m; - - t = escape_html(pa_strna(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION))); -@@ -484,13 +486,16 @@ static void handle_listen(struct connection *c) { - pa_xfree(t); - pa_xfree(m); - } -+ pa_idxset_free(sinks, NULL); - - pa_ioline_puts(c->line, - "

\n" - "

Sources

\n" - "

\n"); - -- PA_IDXSET_FOREACH(source, c->protocol->core->sources, idx) { -+ sources = pa_core_get_sources(c->protocol->core); -+ -+ PA_IDXSET_FOREACH(source, sources, idx) { - char *t, *m; - - if (source->monitor_of) -@@ -507,6 +512,7 @@ static void handle_listen(struct connection *c) { - pa_xfree(t); - - } -+ pa_idxset_free(sources, NULL); - - pa_ioline_puts(c->line, - "

\n" -diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c -index cbb6ae6..4cae6df 100644 ---- a/src/pulsecore/protocol-native.c -+++ b/src/pulsecore/protocol-native.c -@@ -45,7 +45,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -1204,7 +1203,7 @@ static void native_connection_unlink(pa_native_connection *c) { - pa_pstream_unlink(c->pstream); - - if (c->auth_timeout_event) { -- c->protocol->core->mainloop->time_free(c->auth_timeout_event); -+ pa_core_get_mainloop(c->protocol->core)->time_free(c->auth_timeout_event); - c->auth_timeout_event = NULL; - } - -@@ -1875,7 +1874,7 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u - int ret = PA_ERR_INVALID; - uint8_t n_formats = 0; - pa_format_info *format; -- pa_idxset *formats = NULL; -+ pa_idxset *sinks = NULL, *formats = NULL; - uint32_t i; - - pa_native_connection_assert_ref(c); -@@ -2014,8 +2013,9 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u - } - - if (sink_index != PA_INVALID_INDEX) { -+ sinks = pa_core_get_sinks(c->protocol->core); - -- if (!(sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index))) { -+ if (!(sink = pa_idxset_get_by_index(sinks, sink_index))) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); - goto finish; - } -@@ -2105,6 +2105,8 @@ finish: - pa_proplist_free(p); - if (formats) - pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free); -+ if (sinks) -+ pa_idxset_free(sinks, NULL); - } - - static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -@@ -2203,7 +2205,7 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin - int ret = PA_ERR_INVALID; - uint8_t n_formats = 0; - pa_format_info *format; -- pa_idxset *formats = NULL; -+ pa_idxset *sources = NULL, *sink_inputs = NULL, *formats = NULL; - uint32_t i; - - pa_native_connection_assert_ref(c); -@@ -2333,8 +2335,9 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin - } - - if (source_index != PA_INVALID_INDEX) { -+ sources = pa_core_get_sources(c->protocol->core); - -- if (!(source = pa_idxset_get_by_index(c->protocol->core->sources, source_index))) { -+ if (!(source = pa_idxset_get_by_index(sources, source_index))) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); - goto finish; - } -@@ -2348,8 +2351,9 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin - } - - if (direct_on_input_idx != PA_INVALID_INDEX) { -+ sink_inputs = pa_core_get_sink_inputs(c->protocol->core); - -- if (!(direct_on_input = pa_idxset_get_by_index(c->protocol->core->sink_inputs, direct_on_input_idx))) { -+ if (!(direct_on_input = pa_idxset_get_by_index(sink_inputs, direct_on_input_idx))) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); - goto finish; - } -@@ -2419,6 +2423,10 @@ finish: - pa_proplist_free(p); - if (formats) - pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free); -+ if (sources) -+ pa_idxset_free(sources, NULL); -+ if (sink_inputs) -+ pa_idxset_free(sink_inputs, NULL); - } - - static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -@@ -2475,7 +2483,7 @@ static void setup_srbchannel(pa_native_connection *c, pa_mem_type_t shm_type) { - return; - } - -- if (!(c->rw_mempool = pa_mempool_new(shm_type, c->protocol->core->shm_size, true))) { -+ if (!(c->rw_mempool = pa_core_new_mempool(c->protocol->core, shm_type, true))) { - pa_log_warn("Disabling srbchannel, reason: Failed to allocate shared " - "writable memory pool."); - return; -@@ -2490,7 +2498,7 @@ static void setup_srbchannel(pa_native_connection *c, pa_mem_type_t shm_type) { - } - pa_mempool_set_is_remote_writable(c->rw_mempool, true); - -- srb = pa_srbchannel_new(c->protocol->core->mainloop, c->rw_mempool); -+ srb = pa_srbchannel_new(pa_core_get_mainloop(c->protocol->core), c->rw_mempool); - if (!srb) { - pa_log_debug("Failed to create srbchannel"); - goto fail; -@@ -2634,14 +2642,14 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta - - c->authorized = true; - if (c->auth_timeout_event) { -- c->protocol->core->mainloop->time_free(c->auth_timeout_event); -+ pa_core_get_mainloop(c->protocol->core)->time_free(c->auth_timeout_event); - c->auth_timeout_event = NULL; - } - } - - /* Enable shared memory and memfd support if possible */ - do_shm = -- pa_mempool_is_shared(c->protocol->core->mempool) && -+ pa_mempool_is_shared(pa_core_get_mempool(c->protocol->core)) && - c->is_local; - - pa_log_debug("SHM possible: %s", pa_yes_no(do_shm)); -@@ -2668,7 +2676,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta - * 64-bit kernel. Thus influence them to use the POSIX shared memory model - * instead. Check commit 451d1d676237c81 for further details. */ - do_memfd = -- c->version >= 32 && do_shm && pa_mempool_is_memfd_backed(c->protocol->core->mempool); -+ c->version >= 32 && do_shm && pa_mempool_is_memfd_backed(pa_core_get_mempool(c->protocol->core)); - - shm_type = PA_MEM_TYPE_PRIVATE; - if (do_shm) { -@@ -2710,13 +2718,13 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta - if (shm_type == PA_MEM_TYPE_SHARED_MEMFD) { - const char *reason; - -- if (pa_pstream_register_memfd_mempool(c->pstream, c->protocol->core->mempool, &reason)) -+ if (pa_pstream_register_memfd_mempool(c->pstream, pa_core_get_mempool(c->protocol->core), &reason)) - pa_log("Failed to register memfd mempool. Reason: %s", reason); - } - - setup_srbchannel(c, shm_type); - -- pa_hook_fire(&c->protocol->core->hooks[PA_CORE_HOOK_CLIENT_AUTH], c->client); -+ pa_core_hook_fire(c->protocol->core, 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) { -@@ -2842,7 +2850,7 @@ static void command_stat(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - -- stat = pa_mempool_get_stat(c->protocol->core->mempool); -+ stat = pa_mempool_get_stat(pa_core_get_mempool(c->protocol->core)); - - reply = reply_new(tag); - pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->n_allocated)); -@@ -3059,7 +3067,7 @@ static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag - CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID); - - if (sink_index != PA_INVALID_INDEX) -- sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index); -+ sink = pa_core_get_sink(c->protocol->core, sink_index); - else - sink = pa_namereg_get(c->protocol->core, sink_name, PA_NAMEREG_SINK); - -@@ -3522,31 +3530,31 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p - - if (command == PA_COMMAND_GET_SINK_INFO) { - if (idx != PA_INVALID_INDEX) -- sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); -+ sink = pa_core_get_sink(c->protocol->core, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK); - } else if (command == PA_COMMAND_GET_SOURCE_INFO) { - if (idx != PA_INVALID_INDEX) -- source = pa_idxset_get_by_index(c->protocol->core->sources, idx); -+ source = pa_core_get_source(c->protocol->core, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE); - } else if (command == PA_COMMAND_GET_CARD_INFO) { - if (idx != PA_INVALID_INDEX) -- card = pa_idxset_get_by_index(c->protocol->core->cards, idx); -+ card = pa_core_get_card(c->protocol->core, idx); - else - card = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_CARD); - } else if (command == PA_COMMAND_GET_CLIENT_INFO) -- client = pa_idxset_get_by_index(c->protocol->core->clients, idx); -+ client = pa_core_get_client(c->protocol->core, idx); - else if (command == PA_COMMAND_GET_MODULE_INFO) -- module = pa_idxset_get_by_index(c->protocol->core->modules, idx); -+ module = pa_core_get_module(c->protocol->core, idx); - else if (command == PA_COMMAND_GET_SINK_INPUT_INFO) -- si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); -+ si = pa_core_get_sink_input(c->protocol->core, idx); - else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO) -- so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); -+ so = pa_core_get_source_output(c->protocol->core, idx); - else { - pa_assert(command == PA_COMMAND_GET_SAMPLE_INFO); - if (idx != PA_INVALID_INDEX) -- sce = pa_idxset_get_by_index(c->protocol->core->scache, idx); -+ sce = pa_core_get_scache_entry(c->protocol->core, idx); - else - sce = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SAMPLE); - } -@@ -3596,22 +3604,22 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t - reply = reply_new(tag); - - if (command == PA_COMMAND_GET_SINK_INFO_LIST) -- i = c->protocol->core->sinks; -+ i = pa_core_get_sinks(c->protocol->core); - else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST) -- i = c->protocol->core->sources; -+ i = pa_core_get_sources(c->protocol->core); - else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST) -- i = c->protocol->core->clients; -+ i = pa_core_get_clients(c->protocol->core); - else if (command == PA_COMMAND_GET_CARD_INFO_LIST) -- i = c->protocol->core->cards; -+ i = pa_core_get_cards(c->protocol->core); - else if (command == PA_COMMAND_GET_MODULE_INFO_LIST) -- i = c->protocol->core->modules; -+ i = pa_core_get_modules(c->protocol->core); - else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST) -- i = c->protocol->core->sink_inputs; -+ i = pa_core_get_sink_inputs(c->protocol->core); - else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST) -- i = c->protocol->core->source_outputs; -+ i = pa_core_get_source_outputs(c->protocol->core); - else { - pa_assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST); -- i = c->protocol->core->scache; -+ i = pa_core_get_scache(c->protocol->core); - } - - if (i) { -@@ -3635,9 +3643,12 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t - scache_fill_tagstruct(c, reply, p); - } - } -+ -+ pa_idxset_free(i, NULL); - } - - pa_pstream_send_tagstruct(c->pstream, reply); -+ return; - } - - static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -@@ -3658,6 +3669,9 @@ static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - -+ def_sink = pa_namereg_get_default_sink(c->protocol->core); -+ def_source = pa_namereg_get_default_source(c->protocol->core); -+ - reply = reply_new(tag); - pa_tagstruct_puts(reply, PACKAGE_NAME); - pa_tagstruct_puts(reply, PACKAGE_VERSION); -@@ -3670,18 +3684,16 @@ static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t - pa_tagstruct_puts(reply, h); - pa_xfree(h); - -- fixup_sample_spec(c, &fixed_ss, &c->protocol->core->default_sample_spec); -+ fixup_sample_spec(c, &fixed_ss, pa_core_get_sample_spec(c->protocol->core)); - pa_tagstruct_put_sample_spec(reply, &fixed_ss); - -- def_sink = pa_namereg_get_default_sink(c->protocol->core); - pa_tagstruct_puts(reply, def_sink ? def_sink->name : NULL); -- def_source = pa_namereg_get_default_source(c->protocol->core); - pa_tagstruct_puts(reply, def_source ? def_source->name : NULL); - -- pa_tagstruct_putu32(reply, c->protocol->core->cookie); -+ pa_tagstruct_putu32(reply, pa_core_get_cookie(c->protocol->core)); - - if (c->version >= 15) -- pa_tagstruct_put_channel_map(reply, &c->protocol->core->default_channel_map); -+ pa_tagstruct_put_channel_map(reply, pa_core_get_channel_map(c->protocol->core)); - - pa_pstream_send_tagstruct(c->pstream, reply); - } -@@ -3766,24 +3778,24 @@ static void command_set_volume( - - case PA_COMMAND_SET_SINK_VOLUME: - if (idx != PA_INVALID_INDEX) -- sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); -+ sink = pa_core_get_sink(c->protocol->core, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK); - break; - - case PA_COMMAND_SET_SOURCE_VOLUME: - if (idx != PA_INVALID_INDEX) -- source = pa_idxset_get_by_index(c->protocol->core->sources, idx); -+ source = pa_core_get_source(c->protocol->core, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE); - break; - - case PA_COMMAND_SET_SINK_INPUT_VOLUME: -- si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); -+ si = pa_core_get_sink_input(c->protocol->core, idx); - break; - - case PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME: -- so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); -+ so = pa_core_get_source_output(c->protocol->core, idx); - break; - - default: -@@ -3861,7 +3873,7 @@ static void command_set_mute( - - case PA_COMMAND_SET_SINK_MUTE: - if (idx != PA_INVALID_INDEX) -- sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); -+ sink = pa_core_get_sink(c->protocol->core, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK); - -@@ -3869,18 +3881,18 @@ static void command_set_mute( - - case PA_COMMAND_SET_SOURCE_MUTE: - if (idx != PA_INVALID_INDEX) -- source = pa_idxset_get_by_index(c->protocol->core->sources, idx); -+ source = pa_core_get_source(c->protocol->core, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE); - - break; - - case PA_COMMAND_SET_SINK_INPUT_MUTE: -- si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); -+ si = pa_core_get_sink_input(c->protocol->core, idx); - break; - - case PA_COMMAND_SET_SOURCE_OUTPUT_MUTE: -- so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); -+ so = pa_core_get_source_output(c->protocol->core, idx); - break; - - default: -@@ -4425,7 +4437,7 @@ static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta - if (command == PA_COMMAND_KILL_CLIENT) { - pa_client *client; - -- client = pa_idxset_get_by_index(c->protocol->core->clients, idx); -+ client = pa_core_get_client(c->protocol->core, idx); - CHECK_VALIDITY(c->pstream, client, tag, PA_ERR_NOENTITY); - - pa_native_connection_ref(c); -@@ -4434,7 +4446,7 @@ static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta - } else if (command == PA_COMMAND_KILL_SINK_INPUT) { - pa_sink_input *s; - -- s = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); -+ s = pa_core_get_sink_input(c->protocol->core, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - - pa_native_connection_ref(c); -@@ -4444,7 +4456,7 @@ static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta - - pa_assert(command == PA_COMMAND_KILL_SOURCE_OUTPUT); - -- s = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); -+ s = pa_core_get_source_output(c->protocol->core, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - - pa_native_connection_ref(c); -@@ -4500,7 +4512,7 @@ static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t t - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); -- m = pa_idxset_get_by_index(c->protocol->core->modules, idx); -+ m = pa_core_get_module(c->protocol->core, idx); - CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY); - - pa_module_unload_request(m, false); -@@ -4533,10 +4545,10 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag - pa_sink_input *si = NULL; - pa_sink *sink = NULL; - -- si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); -+ si = pa_core_get_sink_input(c->protocol->core, idx); - - if (idx_device != PA_INVALID_INDEX) -- sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx_device); -+ sink = pa_core_get_sink(c->protocol->core, idx_device); - else - sink = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SINK); - -@@ -4552,10 +4564,10 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag - - pa_assert(command == PA_COMMAND_MOVE_SOURCE_OUTPUT); - -- so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); -+ so = pa_core_get_source_output(c->protocol->core, idx); - - if (idx_device != PA_INVALID_INDEX) -- source = pa_idxset_get_by_index(c->protocol->core->sources, idx_device); -+ source = pa_core_get_source(c->protocol->core, idx_device); - else - source = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SOURCE); - -@@ -4605,7 +4617,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa - pa_sink *sink = NULL; - - if (idx != PA_INVALID_INDEX) -- sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); -+ sink = pa_core_get_sink(c->protocol->core, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK); - -@@ -4636,7 +4648,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa - pa_source *source; - - if (idx != PA_INVALID_INDEX) -- source = pa_idxset_get_by_index(c->protocol->core->sources, idx); -+ source = pa_core_get_source(c->protocol->core, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE); - -@@ -4676,12 +4688,17 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, - CHECK_VALIDITY(c->pstream, (idx != PA_INVALID_INDEX) ^ (name != NULL), tag, PA_ERR_INVALID); - - if (idx != PA_INVALID_INDEX) -- m = pa_idxset_get_by_index(c->protocol->core->modules, idx); -- else -- PA_IDXSET_FOREACH(m, c->protocol->core->modules, idx) -+ m = pa_core_get_module(c->protocol->core, idx); -+ else { -+ pa_idxset *modules = pa_core_get_modules (c->protocol->core); -+ -+ PA_IDXSET_FOREACH(m, modules, idx) - if (pa_streq(name, m->name)) - break; - -+ pa_idxset_free (modules, NULL); -+ } -+ - CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOEXTENSION); - CHECK_VALIDITY(c->pstream, m->load_once || idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); - -@@ -4717,7 +4734,7 @@ static void command_set_card_profile(pa_pdispatch *pd, uint32_t command, uint32_ - CHECK_VALIDITY(c->pstream, profile_name, tag, PA_ERR_INVALID); - - if (idx != PA_INVALID_INDEX) -- card = pa_idxset_get_by_index(c->protocol->core->cards, idx); -+ card = pa_core_get_card(c->protocol->core, idx); - else - card = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_CARD); - -@@ -4761,7 +4778,7 @@ static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command, - pa_sink *sink; - - if (idx != PA_INVALID_INDEX) -- sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); -+ sink = pa_core_get_sink(c->protocol->core, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK); - -@@ -4777,7 +4794,7 @@ static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command, - pa_assert(command == PA_COMMAND_SET_SOURCE_PORT); - - if (idx != PA_INVALID_INDEX) -- source = pa_idxset_get_by_index(c->protocol->core->sources, idx); -+ source = pa_core_get_source(c->protocol->core, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE); - -@@ -4818,7 +4835,7 @@ static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command, - CHECK_VALIDITY(c->pstream, port_name, tag, PA_ERR_INVALID); - - if (idx != PA_INVALID_INDEX) -- card = pa_idxset_get_by_index(c->protocol->core->cards, idx); -+ card = pa_core_get_card(c->protocol->core, idx); - else - card = pa_namereg_get(c->protocol->core, card_name, PA_NAMEREG_CARD); - -@@ -5003,7 +5020,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o - pa_memblock_ref(u->memchunk.memblock); - u->length = 0; - } else { -- u->memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, u->length); -+ u->memchunk.memblock = pa_memblock_new(pa_core_get_mempool(c->protocol->core), u->length); - u->memchunk.index = u->memchunk.length = 0; - } - } -@@ -5181,7 +5198,7 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati - - c->rw_mempool = NULL; - -- c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool); -+ c->pstream = pa_pstream_new(pa_core_get_mainloop(p->core), io, pa_core_get_mempool(p->core)); - pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c); - pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c); - pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c); -@@ -5189,7 +5206,7 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati - pa_pstream_set_revoke_callback(c->pstream, pstream_revoke_callback, c); - pa_pstream_set_release_callback(c->pstream, pstream_release_callback, c); - -- c->pdispatch = pa_pdispatch_new(p->core->mainloop, true, command_table, PA_COMMAND_MAX); -+ c->pdispatch = pa_pdispatch_new(pa_core_get_mainloop(p->core), true, command_table, PA_COMMAND_MAX); - - c->record_streams = pa_idxset_new(NULL, NULL); - c->output_streams = pa_idxset_new(NULL, NULL); -diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c -index bd9136b..e1ead2f 100644 ---- a/src/pulsecore/protocol-simple.c -+++ b/src/pulsecore/protocol-simple.c -@@ -34,7 +34,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -169,7 +168,7 @@ static int do_read(connection *c) { - } - - if (!c->playback.current_memblock) { -- pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) -1)); -+ pa_assert_se(c->playback.current_memblock = pa_memblock_new(pa_core_get_mempool(c->protocol->core), (size_t) -1)); - c->playback.memblock_index = 0; - - space = pa_memblock_get_length(c->playback.current_memblock); -@@ -737,7 +736,7 @@ int pa_simple_options_parse(pa_simple_options *o, pa_core *c, pa_modargs *ma) { - pa_assert(PA_REFCNT_VALUE(o) >= 1); - pa_assert(ma); - -- o->sample_spec = c->default_sample_spec; -+ o->sample_spec = *pa_core_get_sample_spec(c); - if (pa_modargs_get_sample_spec_and_channel_map(ma, &o->sample_spec, &o->channel_map, PA_CHANNEL_MAP_DEFAULT) < 0) { - pa_log("Failed to parse sample type specification."); - return -1; -diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c -index 20249ec..a5cb1ee 100644 ---- a/src/pulsecore/sink.c -+++ b/src/pulsecore/sink.c -@@ -2892,17 +2892,21 @@ int pa_sink_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) { - pa_sink *sink; - uint32_t idx; - int ret = 0; -+ pa_idxset *sinks; - - pa_core_assert_ref(c); - pa_assert_ctl_context(); - pa_assert(cause != 0); - -- PA_IDXSET_FOREACH(sink, c->sinks, idx) { -+ sinks = pa_core_get_sinks(c); -+ -+ PA_IDXSET_FOREACH(sink, sinks, idx) { - int r; - - if ((r = pa_sink_suspend(sink, suspend, cause)) < 0) - ret = r; - } -+ pa_idxset_free(sinks, NULL); - - return ret; - } -diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c -index 7a33d5b..5f42965 100644 ---- a/src/pulsecore/source.c -+++ b/src/pulsecore/source.c -@@ -2254,12 +2254,15 @@ int pa_source_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) { - pa_source *source; - uint32_t idx; - int ret = 0; -+ pa_idxset *sources; - - pa_core_assert_ref(c); - pa_assert_ctl_context(); - pa_assert(cause != 0); - -- for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) { -+ sources = pa_core_get_sources(c); -+ -+ PA_IDXSET_FOREACH(source, sources, idx) { - int r; - - if (source->monitor_of) -@@ -2268,6 +2271,7 @@ int pa_source_suspend_all(pa_core *c, bool suspend, pa_suspend_cause_t cause) { - if ((r = pa_source_suspend(source, suspend, cause)) < 0) - ret = r; - } -+ pa_idxset_free(sources, NULL); - - return ret; - } --- -2.9.3 - diff --git a/0011-Add-access-checks.patch b/0011-Add-access-checks.patch deleted file mode 100644 index fb9ec60..0000000 --- a/0011-Add-access-checks.patch +++ /dev/null @@ -1,840 +0,0 @@ -From 70721d64d1bd4428d59cb4038eb56d9d79cf24fc Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Fri, 27 Jan 2017 16:41:41 +0100 -Subject: [PATCH 11/18] Add access checks - -Put some access control checks in various core objects ---- - src/pulsecore/card.c | 6 ++ - src/pulsecore/client.c | 3 + - src/pulsecore/core-scache.c | 12 +++ - src/pulsecore/core-subscribe.c | 6 +- - src/pulsecore/core.c | 176 ++++++++++++++++++++++++++++++++++---- - src/pulsecore/core.h | 4 + - src/pulsecore/module.c | 18 ++++ - src/pulsecore/namereg.c | 27 +++++- - src/pulsecore/protocol-native.c | 1 + - src/pulsecore/sink-input.c | 27 ++++++ - src/pulsecore/sink.c | 22 +++++ - src/pulsecore/sound-file-stream.c | 3 + - src/pulsecore/source-output.c | 21 +++++ - src/pulsecore/source.c | 21 +++++ - 14 files changed, 325 insertions(+), 22 deletions(-) - -diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c -index 39f4261..5018d07 100644 ---- a/src/pulsecore/card.c -+++ b/src/pulsecore/card.c -@@ -296,6 +296,9 @@ int pa_card_set_profile(pa_card *c, pa_card_profile *profile, bool save) { - pa_assert(profile); - pa_assert(profile->card == c); - -+ if (!pa_core_check_access_sync(c->core, PA_ACCESS_HOOK_SET_CARD_PROFILE, c->index, 0, NULL)) -+ return -PA_ERR_ACCESS; -+ - if (!c->set_profile) { - pa_log_debug("set_profile() operation not implemented for card %u \"%s\"", c->index, c->name); - return -PA_ERR_NOTIMPLEMENTED; -@@ -378,6 +381,9 @@ int pa_card_suspend(pa_card *c, bool suspend, pa_suspend_cause_t cause) { - pa_assert(c); - pa_assert(cause != 0); - -+ if (!pa_core_check_access_sync(c->core, PA_ACCESS_HOOK_SUSPEND_CARD, c->index, 0, NULL)) -+ return -1; -+ - suspend_cause = c->suspend_cause; - - if (suspend) -diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c -index 24faa1f..fa10ae1 100644 ---- a/src/pulsecore/client.c -+++ b/src/pulsecore/client.c -@@ -112,6 +112,9 @@ void pa_client_free(pa_client *c) { - void pa_client_kill(pa_client *c) { - pa_assert(c); - -+ if (!pa_core_check_access_sync(c->core, PA_ACCESS_HOOK_KILL_CLIENT, c->index, 0, NULL)) -+ return; -+ - if (!c->kill) { - pa_log_warn("kill() operation not implemented for client %u", c->index); - return; -diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c -index 8d54720..4eaa997 100644 ---- a/src/pulsecore/core-scache.c -+++ b/src/pulsecore/core-scache.c -@@ -97,6 +97,9 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name, bool *new_ - pa_assert(name); - pa_assert(new_sample); - -+ if (!pa_core_check_access_sync(c, PA_ACCESS_HOOK_ADD_SAMPLE, PA_INVALID_INDEX, 0, name)) -+ return NULL; -+ - if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE))) { - if (e->memchunk.memblock) - pa_memblock_unref(e->memchunk.memblock); -@@ -281,6 +284,9 @@ int pa_scache_remove_item(pa_core *c, const char *name) { - if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE))) - return -1; - -+ if (!pa_core_check_access_sync(c, PA_ACCESS_HOOK_REMOVE_SAMPLE, PA_INVALID_INDEX, 0, name)) -+ return -1; -+ - pa_assert_se(pa_idxset_remove_by_data(c->scache, e, NULL) == e); - - pa_log_debug("Removed sample \"%s\"", name); -@@ -293,6 +299,9 @@ int pa_scache_remove_item(pa_core *c, const char *name) { - void pa_scache_free_all(pa_core *c) { - pa_assert(c); - -+ if (!pa_core_check_access_sync(c, PA_ACCESS_HOOK_REMOVE_SAMPLE, PA_INVALID_INDEX, 0, NULL)) -+ return; -+ - pa_idxset_remove_all(c->scache, (pa_free_cb_t) free_entry); - - if (c->scache_auto_unload_event) { -@@ -314,6 +323,9 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t - if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE))) - return -1; - -+ if (!pa_core_check_access_sync(c, PA_ACCESS_HOOK_PLAY_SAMPLE, e->index, 0, NULL)) -+ return -1; -+ - merged = pa_proplist_new(); - pa_proplist_sets(merged, PA_PROP_MEDIA_NAME, name); - pa_proplist_sets(merged, PA_PROP_EVENT_ID, name); -diff --git a/src/pulsecore/core-subscribe.c b/src/pulsecore/core-subscribe.c -index 88d900b..e60af21 100644 ---- a/src/pulsecore/core-subscribe.c -+++ b/src/pulsecore/core-subscribe.c -@@ -169,8 +169,10 @@ static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) { - - for (s = c->subscriptions; s; s = s->next) { - -- if (!s->dead && pa_subscription_match_flags(s->mask, e->type)) -- s->callback(c, e->type, e->index, s->userdata); -+ if (!s->dead && pa_subscription_match_flags(s->mask, e->type)) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_FILTER_SUBSCRIBE_EVENT, e->index, e->type, NULL)) -+ s->callback(c, e->type, e->index, s->userdata); -+ } - } - - #ifdef DEBUG -diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c -index b068f5d..6b9fb8b 100644 ---- a/src/pulsecore/core.c -+++ b/src/pulsecore/core.c -@@ -257,6 +257,8 @@ int pa_core_exit(pa_core *c, bool force, int retval) { - - if (c->disallow_exit && !force) - return -1; -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_EXIT_DAEMON, PA_INVALID_INDEX, 0, NULL)) -+ return -1; - - c->mainloop->quit(c->mainloop, retval); - return 0; -@@ -330,70 +332,212 @@ pa_mempool* pa_core_new_mempool(pa_core *c, pa_mem_type_t shm_type, bool per_cli - return pa_mempool_new(shm_type, c->shm_size, per_client); - } - -+bool pa_core_check_access_sync(pa_core *c, pa_access_hook_t hook, uint32_t idx, pa_subscription_event_type_t event, const char *name) { -+ pa_access_data data; -+ -+ pa_assert(c); -+ -+ if (c->current_client == NULL) -+ return true; -+ -+ data.hook = hook; -+ data.client_index = c->current_client->index; -+ data.object_index = idx; -+ data.event = event; -+ data.name = name; -+ data.complete_cb = NULL; -+ -+ return pa_hook_fire(&c->access[data.hook], &data) == PA_HOOK_OK; -+} -+ -+pa_hook_result_t pa_core_check_access(pa_core *c, pa_access_data *data) { -+ pa_assert(c); -+ pa_assert(data); -+ -+ if (c->current_client == NULL) -+ return PA_HOOK_OK; -+ -+ data->client_index = c->current_client->index; -+ -+ return pa_hook_fire(&c->access[data->hook], data); -+} -+ - /* FIXME: Should these be taking a ref during the copy? */ - - pa_idxset* pa_core_get_modules(pa_core *c) { -- return pa_idxset_copy(c->modules, NULL); -+ pa_idxset *s; -+ uint32_t idx; -+ pa_module *e; -+ -+ s = pa_idxset_new(NULL, NULL); -+ PA_IDXSET_FOREACH(e, c->modules, idx) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_MODULE, e->index, 0, NULL)) -+ pa_idxset_put(s, e, NULL); -+ } -+ return s; - } - - pa_idxset* pa_core_get_clients(pa_core *c) { -- return pa_idxset_copy(c->clients, NULL); -+ pa_idxset *s; -+ uint32_t idx; -+ pa_client *e; -+ -+ s = pa_idxset_new(NULL, NULL); -+ PA_IDXSET_FOREACH(e, c->clients, idx) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_CLIENT, e->index, 0, NULL)) -+ pa_idxset_put(s, e, NULL); -+ } -+ return s; - } - - pa_idxset* pa_core_get_cards(pa_core *c) { -- return pa_idxset_copy(c->cards, NULL); -+ pa_idxset *s; -+ uint32_t idx; -+ pa_card *e; -+ -+ s = pa_idxset_new(NULL, NULL); -+ PA_IDXSET_FOREACH(e, c->cards, idx) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_CARD, e->index, 0, NULL)) -+ pa_idxset_put(s, e, NULL); -+ } -+ return s; - } - - pa_idxset* pa_core_get_sinks(pa_core *c) { -- return pa_idxset_copy(c->sinks, NULL); -+ pa_idxset *s; -+ uint32_t idx; -+ pa_sink *e; -+ -+ s = pa_idxset_new(NULL, NULL); -+ PA_IDXSET_FOREACH(e, c->sinks, idx) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SINK, e->index, 0, NULL)) -+ pa_idxset_put(s, e, NULL); -+ } -+ return s; - } - - pa_idxset* pa_core_get_sources(pa_core *c) { -- return pa_idxset_copy(c->sources, NULL); -+ pa_idxset *s; -+ uint32_t idx; -+ pa_source *e; -+ -+ s = pa_idxset_new(NULL, NULL); -+ PA_IDXSET_FOREACH(e, c->sources, idx) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SOURCE, e->index, 0, NULL)) -+ pa_idxset_put(s, e, NULL); -+ } -+ return s; - } - - pa_idxset* pa_core_get_sink_inputs(pa_core *c) { -- return pa_idxset_copy(c->sink_inputs, NULL); -+ pa_idxset *s; -+ uint32_t idx; -+ pa_sink_input *e; -+ -+ s = pa_idxset_new(NULL, NULL); -+ PA_IDXSET_FOREACH(e, c->sink_inputs, idx) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SINK_INPUT, e->index, 0, NULL)) -+ pa_idxset_put(s, e, NULL); -+ } -+ return s; - } - - pa_idxset* pa_core_get_source_outputs(pa_core *c) { -- return pa_idxset_copy(c->source_outputs, NULL); -+ pa_idxset *s; -+ uint32_t idx; -+ pa_source_output *e; -+ -+ s = pa_idxset_new(NULL, NULL); -+ PA_IDXSET_FOREACH(e, c->source_outputs, idx) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT, e->index, 0, NULL)) -+ pa_idxset_put(s, e, NULL); -+ } -+ return s; - } - - pa_idxset* pa_core_get_scache(pa_core *c) { -- return pa_idxset_copy(c->scache, NULL); -+ pa_idxset *s; -+ uint32_t idx; -+ pa_scache_entry *e; -+ -+ s = pa_idxset_new(NULL, NULL); -+ PA_IDXSET_FOREACH(e, c->scache, idx) { -+ if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SAMPLE, e->index, 0, NULL)) -+ pa_idxset_put(s, e, NULL); -+ } -+ return s; - } - - pa_module* pa_core_get_module(pa_core *c, uint32_t idx) { -- return pa_idxset_get_by_index(c->modules, idx); -+ pa_module *e = pa_idxset_get_by_index(c->modules, idx); -+ -+ if (e == NULL || !pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_MODULE, e->index, 0, NULL)) -+ return NULL; -+ -+ return e; - } - - pa_client* pa_core_get_client(pa_core *c, uint32_t idx) { -- return pa_idxset_get_by_index(c->clients, idx); -+ pa_client *e = pa_idxset_get_by_index(c->clients, idx); -+ -+ if (e == NULL || !pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_CLIENT, e->index, 0, NULL)) -+ return NULL; -+ -+ return e; - } - - pa_card* pa_core_get_card(pa_core *c, uint32_t idx) { -- return pa_idxset_get_by_index(c->cards, idx); -+ pa_card *e = pa_idxset_get_by_index(c->cards, idx); -+ -+ if (e == NULL || !pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_CARD, e->index, 0, NULL)) -+ return NULL; -+ -+ return e; - } - - pa_sink* pa_core_get_sink(pa_core *c, uint32_t idx) { -- return pa_idxset_get_by_index(c->sinks, idx); -+ pa_sink *e = pa_idxset_get_by_index(c->sinks, idx); -+ -+ if (e == NULL || !pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SINK, e->index, 0, NULL)) -+ return NULL; -+ -+ return e; - } - - pa_source* pa_core_get_source(pa_core *c, uint32_t idx) { -- return pa_idxset_get_by_index(c->sources, idx); -+ pa_source *e = pa_idxset_get_by_index(c->sources, idx); -+ -+ if (e == NULL || !pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SOURCE, e->index, 0, NULL)) -+ return NULL; -+ -+ return e; - } - - pa_sink_input* pa_core_get_sink_input(pa_core *c, uint32_t idx) { -- return pa_idxset_get_by_index(c->sink_inputs, idx); -+ pa_sink_input *e = pa_idxset_get_by_index(c->sink_inputs, idx); -+ -+ if (e == NULL || !pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SINK_INPUT, e->index, 0, NULL)) -+ return NULL; -+ -+ return e; - } - - pa_source_output* pa_core_get_source_output(pa_core *c, uint32_t idx) { -- return pa_idxset_get_by_index(c->source_outputs, idx); -+ pa_source_output *e = pa_idxset_get_by_index(c->source_outputs, idx); -+ -+ if (e == NULL || !pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT, e->index, 0, NULL)) -+ return NULL; -+ -+ return e; - } - - pa_scache_entry* pa_core_get_scache_entry(pa_core *c, uint32_t idx) { -- return pa_idxset_get_by_index(c->scache, idx); -+ pa_scache_entry *e = pa_idxset_get_by_index(c->scache, idx); -+ -+ if (e == NULL || !pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SAMPLE, e->index, 0, NULL)) -+ return NULL; -+ -+ return e; - } - - const pa_sample_spec* pa_core_get_sample_spec(pa_core *c) { -diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h -index 87b055d..316a88e 100644 ---- a/src/pulsecore/core.h -+++ b/src/pulsecore/core.h -@@ -192,4 +192,8 @@ const pa_channel_map* pa_core_get_channel_map(pa_core *c); - - uint32_t pa_core_get_cookie(pa_core *c); - -+bool pa_core_check_access_sync(pa_core *c, pa_access_hook_t hook, uint32_t idx, pa_subscription_event_type_t event, const char *name); -+ -+pa_hook_result_t pa_core_check_access(pa_core *c, pa_access_data *data); -+ - #endif -diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c -index da2abe0..bcc1a0e 100644 ---- a/src/pulsecore/module.c -+++ b/src/pulsecore/module.c -@@ -120,6 +120,9 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { - if (c->disallow_module_loading) - goto fail; - -+ if (!pa_core_check_access_sync(c, PA_ACCESS_HOOK_LOAD_MODULE, PA_INVALID_INDEX, 0, name)) -+ goto fail; -+ - m = pa_xnew(pa_module, 1); - m->name = pa_xstrdup(name); - m->argument = pa_xstrdup(argument); -@@ -280,6 +283,9 @@ void pa_module_unload(pa_module *m, bool force) { - if (m->core->disallow_module_loading && !force) - return; - -+ if (!pa_core_check_access_sync(m->core, PA_ACCESS_HOOK_UNLOAD_MODULE, m->index, 0, NULL)) -+ return; -+ - if (!(m = pa_idxset_remove_by_data(m->core->modules, m, NULL))) - return; - -@@ -294,6 +300,9 @@ void pa_module_unload_by_index(pa_core *c, uint32_t idx, bool force) { - if (c->disallow_module_loading && !force) - return; - -+ if (!pa_core_check_access_sync(c, PA_ACCESS_HOOK_UNLOAD_MODULE, idx, 0, NULL)) -+ return; -+ - if (!(m = pa_idxset_remove_by_index(c->modules, idx))) - return; - -@@ -312,6 +321,9 @@ void pa_module_unload_all(pa_core *c) { - if (pa_idxset_isempty(c->modules)) - return; - -+ if (!pa_core_check_access_sync(c, PA_ACCESS_HOOK_UNLOAD_MODULE, PA_INVALID_INDEX, 0, NULL)) -+ return; -+ - /* Unload modules in reverse order by default */ - indices = pa_xnew(uint32_t, pa_idxset_size(c->modules)); - i = 0; -@@ -357,6 +369,9 @@ void pa_module_unload_request(pa_module *m, bool force) { - if (m->core->disallow_module_loading && !force) - return; - -+ if (!pa_core_check_access_sync(m->core, PA_ACCESS_HOOK_UNLOAD_MODULE, m->index, 0, NULL)) -+ return; -+ - m->unload_requested = true; - pa_hashmap_put(m->core->modules_pending_unload, m, m); - -@@ -370,6 +385,9 @@ void pa_module_unload_request_by_index(pa_core *c, uint32_t idx, bool force) { - pa_module *m; - pa_assert(c); - -+ if (!pa_core_check_access_sync(c, PA_ACCESS_HOOK_UNLOAD_MODULE, idx, 0, NULL)) -+ return; -+ - if (!(m = pa_idxset_get_by_index(c->modules, idx))) - return; - -diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c -index 699fa1b..fb68faf 100644 ---- a/src/pulsecore/namereg.c -+++ b/src/pulsecore/namereg.c -@@ -232,9 +232,20 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) { - !pa_namereg_is_valid_name(name)) - return NULL; - -- if ((e = pa_hashmap_get(c->namereg, name))) -- if (e->type == type) -+ if ((e = pa_hashmap_get(c->namereg, name)) && e->type == type) { -+ if (type == PA_NAMEREG_SINK && -+ pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SINK, ((pa_sink*)e->data)->index, 0, NULL)) - return e->data; -+ else if (type == PA_NAMEREG_SOURCE && -+ pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SOURCE, ((pa_source*)e->data)->index, 0, NULL)) -+ return e->data; -+ else if (type == PA_NAMEREG_SAMPLE && -+ pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SAMPLE, ((pa_scache_entry*)e->data)->index, 0, NULL)) -+ return e->data; -+ else if (type == PA_NAMEREG_CARD && -+ pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_CARD, ((pa_card*)e->data)->index, 0, NULL)) -+ return e->data; -+ } - - if (pa_atou(name, &idx) < 0) - return NULL; -@@ -257,6 +268,9 @@ pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) { - if (s && !PA_SINK_IS_LINKED(pa_sink_get_state(s))) - return NULL; - -+ if (s && !pa_core_check_access_sync(c, PA_ACCESS_HOOK_SET_DEFAULT_SINK, s->index, 0, NULL)) -+ return NULL; -+ - if (c->default_sink != s) { - c->default_sink = s; - pa_core_hook_fire(c, PA_CORE_HOOK_DEFAULT_SINK_CHANGED, c->default_sink); -@@ -272,6 +286,9 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) { - if (s && !PA_SOURCE_IS_LINKED(pa_source_get_state(s))) - return NULL; - -+ if (s && !pa_core_check_access_sync(c, PA_ACCESS_HOOK_SET_DEFAULT_SOURCE, s->index, 0, NULL)) -+ return NULL; -+ - if (c->default_source != s) { - c->default_source = s; - pa_core_hook_fire(c, PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED, c->default_source); -@@ -288,7 +305,8 @@ pa_sink *pa_namereg_get_default_sink(pa_core *c) { - - pa_assert(c); - -- if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink))) -+ if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)) && -+ pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SINK, c->default_sink->index, 0, NULL)) - return c->default_sink; - - sinks = pa_core_get_sinks(c); -@@ -310,7 +328,8 @@ pa_source *pa_namereg_get_default_source(pa_core *c) { - - pa_assert(c); - -- if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source))) -+ if (c->default_source && PA_SOURCE_IS_LINKED(pa_source_get_state(c->default_source)) && -+ pa_core_check_access_sync(c, PA_ACCESS_HOOK_VIEW_SOURCE, c->default_source->index, 0, NULL)) - return c->default_source; - - sources = pa_core_get_sources(c); -diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c -index 4cae6df..4ff97c4 100644 ---- a/src/pulsecore/protocol-native.c -+++ b/src/pulsecore/protocol-native.c -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c -index 9a866b4..00c370a 100644 ---- a/src/pulsecore/sink-input.c -+++ b/src/pulsecore/sink-input.c -@@ -297,6 +297,9 @@ int pa_sink_input_new( - pa_assert(data); - pa_assert_ctl_context(); - -+ if (!pa_core_check_access_sync(core, PA_ACCESS_HOOK_CREATE_SINK_INPUT, PA_INVALID_INDEX, 0, NULL)) -+ return -PA_ERR_ACCESS; -+ - if (data->client) - pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist); - -@@ -811,6 +814,9 @@ void pa_sink_input_kill(pa_sink_input*i) { - pa_assert_ctl_context(); - pa_assert(PA_SINK_INPUT_IS_LINKED(i->state)); - -+ if (!pa_core_check_access_sync(i->core, PA_ACCESS_HOOK_KILL_SINK_INPUT, i->index, 0, NULL)) -+ return; -+ - i->kill(i); - } - -@@ -1238,6 +1244,9 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, bool s - pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec)); - pa_assert(i->volume_writable); - -+ if (!pa_core_check_access_sync(i->core, PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME, i->index, 0, NULL)) -+ return; -+ - if (!absolute && pa_sink_flat_volume_enabled(i->sink)) { - v = i->sink->reference_volume; - pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map); -@@ -1289,6 +1298,9 @@ void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa - pa_assert(pa_cvolume_valid(volume_factor)); - pa_assert(volume_factor->channels == 1 || pa_cvolume_compatible(volume_factor, &i->sample_spec)); - -+ if (!pa_core_check_access_sync(i->core, PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME, i->index, 0, NULL)) -+ return; -+ - v = volume_factor_entry_new(key, volume_factor); - if (!pa_cvolume_compatible(volume_factor, &i->sample_spec)) - pa_cvolume_set(&v->volume, i->sample_spec.channels, volume_factor->values[0]); -@@ -1315,6 +1327,9 @@ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) { - pa_assert_ctl_context(); - pa_assert(PA_SINK_INPUT_IS_LINKED(i->state)); - -+ if (!pa_core_check_access_sync(i->core, PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME, i->index, 0, NULL)) -+ return -1; -+ - if (pa_hashmap_remove_and_free(i->volume_factor_items, key) < 0) - return -1; - -@@ -1403,6 +1418,9 @@ void pa_sink_input_set_mute(pa_sink_input *i, bool mute, bool save) { - pa_assert_ctl_context(); - pa_assert(PA_SINK_INPUT_IS_LINKED(i->state)); - -+ if (!pa_core_check_access_sync(i->core, PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME, i->index, 0, NULL)) -+ return; -+ - old_mute = i->muted; - - if (mute == old_mute) { -@@ -1625,6 +1643,12 @@ bool pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) { - if (!pa_sink_input_may_move(i)) - return false; - -+ if (!pa_core_check_access_sync(i->core, PA_ACCESS_HOOK_MOVE_SINK_INPUT, i->index, 0, NULL)) -+ return false; -+ -+ if (!pa_core_check_access_sync(i->core, PA_ACCESS_HOOK_VIEW_SINK, dest->index, 0, NULL)) -+ return false; -+ - /* Make sure we're not creating a filter sink cycle */ - if (find_filter_sink_input(i, dest)) { - pa_log_debug("Can't connect input to %s, as that would create a cycle.", dest->name); -@@ -2332,6 +2356,9 @@ void pa_sink_input_set_volume_direct(pa_sink_input *i, const pa_cvolume *volume) - pa_assert(i); - pa_assert(volume); - -+ if (!pa_core_check_access_sync(i->core, PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME, i->index, 0, NULL)) -+ return; -+ - old_volume = i->volume; - - if (pa_cvolume_equal(volume, &old_volume)) -diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c -index a5cb1ee..891c55c 100644 ---- a/src/pulsecore/sink.c -+++ b/src/pulsecore/sink.c -@@ -839,6 +839,9 @@ int pa_sink_suspend(pa_sink *s, bool suspend, pa_suspend_cause_t cause) { - pa_assert(PA_SINK_IS_LINKED(s->state)); - pa_assert(cause != 0); - -+ if (!pa_core_check_access_sync (s->core, PA_ACCESS_HOOK_SUSPEND_SINK, s->index, 0, NULL)) -+ return -PA_ERR_ACCESS; -+ - if (suspend) { - s->suspend_cause |= cause; - s->monitor_source->suspend_cause |= cause; -@@ -1610,6 +1613,9 @@ bool pa_sink_is_passthrough(pa_sink *s) { - void pa_sink_enter_passthrough(pa_sink *s) { - pa_cvolume volume; - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_ENTER_PASSTHROUGH_SINK, s->index, 0, NULL)) -+ return; -+ - /* disable the monitor in passthrough mode */ - if (s->monitor_source) { - pa_log_debug("Suspending monitor source %s, because the sink is entering the passthrough mode.", s->monitor_source->name); -@@ -1626,6 +1632,10 @@ void pa_sink_enter_passthrough(pa_sink *s) { - - /* Called from main context */ - void pa_sink_leave_passthrough(pa_sink *s) { -+ -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_LEAVE_PASSTHROUGH_SINK, s->index, 0, NULL)) -+ return; -+ - /* Unsuspend monitor */ - if (s->monitor_source) { - pa_log_debug("Resuming monitor source %s, because the sink is leaving the passthrough mode.", s->monitor_source->name); -@@ -2013,6 +2023,9 @@ void pa_sink_set_volume( - pa_assert(volume || pa_sink_flat_volume_enabled(s)); - pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec)); - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_SET_SINK_VOLUME, s->index, 0, NULL)) -+ return; -+ - /* make sure we don't change the volume when a PASSTHROUGH input is connected ... - * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */ - if (pa_sink_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) { -@@ -2229,6 +2242,9 @@ void pa_sink_set_mute(pa_sink *s, bool mute, bool save) { - pa_sink_assert_ref(s); - pa_assert_ctl_context(); - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_SET_SINK_VOLUME, s->index, 0, NULL)) -+ return; -+ - old_muted = s->muted; - - if (mute == old_muted) { -@@ -3280,6 +3296,9 @@ void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) { - void pa_sink_set_port_latency_offset(pa_sink *s, int64_t offset) { - pa_sink_assert_ref(s); - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_SET_SINK_PORT_LATENCY_OFFSET, s->index, 0, NULL)) -+ return; -+ - s->port_latency_offset = offset; - - if (PA_SINK_IS_LINKED(s->state)) -@@ -3332,6 +3351,9 @@ int pa_sink_set_port(pa_sink *s, const char *name, bool save) { - if (!name) - return -PA_ERR_NOENTITY; - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_SET_SINK_PORT, s->index, 0, name)) -+ return -PA_ERR_ACCESS; -+ - if (!(port = pa_hashmap_get(s->ports, name))) - return -PA_ERR_NOENTITY; - -diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c -index 3ac935d..985de6b 100644 ---- a/src/pulsecore/sound-file-stream.c -+++ b/src/pulsecore/sound-file-stream.c -@@ -242,6 +242,9 @@ int pa_play_file( - pa_assert(sink); - pa_assert(fname); - -+ if (!pa_core_check_access_sync (sink->core, PA_ACCESS_HOOK_PLAY_FILE, PA_INVALID_INDEX, 0, fname)) -+ return -1; -+ - u = pa_msgobject_new(file_stream); - u->parent.parent.free = file_stream_free; - u->parent.process_msg = file_stream_process_msg; -diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c -index a265e6f..872ee27 100644 ---- a/src/pulsecore/source-output.c -+++ b/src/pulsecore/source-output.c -@@ -231,6 +231,9 @@ int pa_source_output_new( - pa_assert(data); - pa_assert_ctl_context(); - -+ if (!pa_core_check_access_sync(core, PA_ACCESS_HOOK_CREATE_SOURCE_OUTPUT, PA_INVALID_INDEX, 0, NULL)) -+ return -PA_ERR_ACCESS; -+ - if (data->client) - pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist); - -@@ -687,6 +690,9 @@ void pa_source_output_kill(pa_source_output*o) { - pa_assert_ctl_context(); - pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); - -+ if (!pa_core_check_access_sync(o->core, PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT, o->index, 0, NULL)) -+ return; -+ - o->kill(o); - } - -@@ -945,6 +951,9 @@ void pa_source_output_set_volume(pa_source_output *o, const pa_cvolume *volume, - pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &o->sample_spec)); - pa_assert(o->volume_writable); - -+ if (!pa_core_check_access_sync(o->core, PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME, o->index, 0, NULL)) -+ return; -+ - if (!absolute && pa_source_flat_volume_enabled(o->source)) { - v = o->source->reference_volume; - pa_cvolume_remap(&v, &o->source->channel_map, &o->channel_map); -@@ -1056,6 +1065,9 @@ void pa_source_output_set_mute(pa_source_output *o, bool mute, bool save) { - pa_assert_ctl_context(); - pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state)); - -+ if (!pa_core_check_access_sync(o->core, PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME, o->index, 0, NULL)) -+ return; -+ - old_mute = o->muted; - - if (mute == old_mute) { -@@ -1275,6 +1287,12 @@ bool pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) { - if (!pa_source_output_may_move(o)) - return false; - -+ if (!pa_core_check_access_sync(o->core, PA_ACCESS_HOOK_MOVE_SOURCE_OUTPUT, o->index, 0, NULL)) -+ return false; -+ -+ if (!pa_core_check_access_sync(o->core, PA_ACCESS_HOOK_VIEW_SOURCE, dest->index, 0, NULL)) -+ return false; -+ - /* Make sure we're not creating a filter source cycle */ - if (find_filter_source_output(o, dest)) { - pa_log_debug("Can't connect output to %s, as that would create a cycle.", dest->name); -@@ -1787,6 +1805,9 @@ void pa_source_output_set_volume_direct(pa_source_output *o, const pa_cvolume *v - pa_assert(o); - pa_assert(volume); - -+ if (!pa_core_check_access_sync(o->core, PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME, o->index, 0, NULL)) -+ return; -+ - old_volume = o->volume; - - if (pa_cvolume_equal(volume, &old_volume)) -diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c -index 5f42965..449aeff 100644 ---- a/src/pulsecore/source.c -+++ b/src/pulsecore/source.c -@@ -763,6 +763,9 @@ int pa_source_suspend(pa_source *s, bool suspend, pa_suspend_cause_t cause) { - if (s->monitor_of && cause != PA_SUSPEND_PASSTHROUGH) - return -PA_ERR_NOTSUPPORTED; - -+ if (!pa_core_check_access_sync (s->core, PA_ACCESS_HOOK_SUSPEND_SOURCE, s->index, 0, NULL)) -+ return -PA_ERR_ACCESS; -+ - if (suspend) - s->suspend_cause |= cause; - else -@@ -1196,6 +1199,9 @@ bool pa_source_is_passthrough(pa_source *s) { - void pa_source_enter_passthrough(pa_source *s) { - pa_cvolume volume; - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_ENTER_PASSTHROUGH_SOURCE, s->index, 0, NULL)) -+ return; -+ - /* set the volume to NORM */ - s->saved_volume = *pa_source_get_volume(s, true); - s->saved_save_volume = s->save_volume; -@@ -1206,6 +1212,9 @@ void pa_source_enter_passthrough(pa_source *s) { - - /* Called from main context */ - void pa_source_leave_passthrough(pa_source *s) { -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_LEAVE_PASSTHROUGH_SOURCE, s->index, 0, NULL)) -+ return; -+ - /* Restore source volume to what it was before we entered passthrough mode */ - pa_source_set_volume(s, &s->saved_volume, true, s->saved_save_volume); - -@@ -1587,6 +1596,9 @@ void pa_source_set_volume( - pa_assert(volume || pa_source_flat_volume_enabled(s)); - pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec)); - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_SET_SOURCE_VOLUME, s->index, 0, NULL)) -+ return; -+ - /* make sure we don't change the volume in PASSTHROUGH mode ... - * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */ - if (pa_source_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) { -@@ -1812,6 +1824,9 @@ void pa_source_set_mute(pa_source *s, bool mute, bool save) { - pa_source_assert_ref(s); - pa_assert_ctl_context(); - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_SET_SOURCE_VOLUME, s->index, 0, NULL)) -+ return; -+ - old_muted = s->muted; - - if (mute == old_muted) { -@@ -2571,6 +2586,9 @@ void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency) - void pa_source_set_port_latency_offset(pa_source *s, int64_t offset) { - pa_source_assert_ref(s); - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_SET_SOURCE_PORT_LATENCY_OFFSET, s->index, 0, NULL)) -+ return; -+ - s->port_latency_offset = offset; - - if (PA_SOURCE_IS_LINKED(s->state)) -@@ -2609,6 +2627,9 @@ int pa_source_set_port(pa_source *s, const char *name, bool save) { - if (!name) - return -PA_ERR_NOENTITY; - -+ if (!pa_core_check_access_sync(s->core, PA_ACCESS_HOOK_SET_SOURCE_PORT, s->index, 0, name)) -+ return -PA_ERR_ACCESS; -+ - if (!(port = pa_hashmap_get(s->ports, name))) - return -PA_ERR_NOENTITY; - --- -2.9.3 - diff --git a/0012-protocol-native-add-async-access-checks.patch b/0012-protocol-native-add-async-access-checks.patch deleted file mode 100644 index 2a746c3..0000000 --- a/0012-protocol-native-add-async-access-checks.patch +++ /dev/null @@ -1,129 +0,0 @@ -From fe86adb46f57c8b8ef683591506cbe98fff0c071 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Fri, 27 Jan 2017 16:42:34 +0100 -Subject: [PATCH 12/18] protocol-native: add async access checks - ---- - src/pulsecore/protocol-native.c | 91 +++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 87 insertions(+), 4 deletions(-) - -diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c -index 4ff97c4..a866802 100644 ---- a/src/pulsecore/protocol-native.c -+++ b/src/pulsecore/protocol-native.c -@@ -4850,14 +4850,97 @@ static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command, - pa_pstream_send_simple_ack(c->pstream, tag); - } - -+typedef struct pa_protocol_native_access_data { -+ pa_access_data d; -+ -+ pa_pdispatch *pd; -+ uint32_t command; -+ uint32_t tag; -+ pa_tagstruct *tc; -+ void *userdata; -+} pa_protocol_native_access_data; -+ -+static const pa_pdispatch_cb_t access_ok_table[PA_COMMAND_MAX] = { -+ [PA_COMMAND_CREATE_PLAYBACK_STREAM] = command_create_playback_stream, -+ [PA_COMMAND_CREATE_RECORD_STREAM] = command_create_record_stream, -+ [PA_COMMAND_CREATE_UPLOAD_STREAM] = command_create_upload_stream, -+ [PA_COMMAND_STAT] = command_stat, -+}; -+ -+static void check_access_finish_cb(pa_access_data *data, bool res) { -+ pa_protocol_native_access_data *d = (pa_protocol_native_access_data *) data; -+ pa_native_connection *c = PA_NATIVE_CONNECTION(d->userdata); -+ uint32_t command, tag; -+ -+ if (!res || pa_tagstruct_getu32(d->tc, &command) < 0 || -+ pa_tagstruct_getu32(d->tc, &tag) < 0 || -+ command != d->command || tag != d->tag) { -+ pa_pstream_send_error(c->pstream, d->tag, PA_ERR_ACCESS); -+ goto finish; -+ } -+ -+ /* call the dispatcher again, hopefully this time, the access check will -+ * fail or succeed immediately */ -+ access_ok_table[d->command](d->pd, d->command, d->tag, d->tc, d->userdata); -+ -+finish: -+ if (d->pd) -+ pa_pdispatch_unref(d->pd); -+ if (d->tc) -+ pa_tagstruct_free(d->tc); -+ pa_xfree(d); -+} -+ -+static const pa_access_hook_t access_table[PA_COMMAND_MAX] = { -+ [PA_COMMAND_CREATE_PLAYBACK_STREAM] = PA_ACCESS_HOOK_CONNECT_PLAYBACK, -+ [PA_COMMAND_CREATE_RECORD_STREAM] = PA_ACCESS_HOOK_CONNECT_RECORD, -+ [PA_COMMAND_CREATE_UPLOAD_STREAM] = PA_ACCESS_HOOK_CONNECT_UPLOAD, -+ [PA_COMMAND_STAT] = PA_ACCESS_HOOK_STAT, -+}; -+ -+static void check_command_access(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -+ pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); -+ pa_protocol_native_access_data *data; -+ pa_hook_result_t res; -+ -+ pa_native_connection_assert_ref(c); -+ -+ if (access_table[command] == 0) { -+ pa_pstream_send_error(c->pstream, tag, PA_ERR_ACCESS); -+ return; -+ } -+ -+ data = pa_xnew0 (pa_protocol_native_access_data, 1); -+ data->d.client_index = c->client->index; -+ data->d.object_index = PA_INVALID_INDEX; -+ data->d.event = 0; -+ data->d.name = NULL; -+ data->d.hook = access_table[command]; -+ -+ res = pa_core_check_access(c->protocol->core, &data->d); -+ if (res == PA_HOOK_CANCEL) { -+ /* async */ -+ data->d.complete_cb = check_access_finish_cb; -+ data->pd = pd ? pa_pdispatch_ref (pd) : NULL; -+ data->command = command; -+ data->tag = tag; -+ data->tc = t ? pa_tagstruct_copy (t) : NULL; -+ data->userdata = userdata; -+ } else { -+ pa_xfree(data); -+ access_ok_table[command](pd, command, tag, t, userdata); -+ } -+} -+ -+ - static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { - [PA_COMMAND_ERROR] = NULL, - [PA_COMMAND_TIMEOUT] = NULL, - [PA_COMMAND_REPLY] = NULL, -- [PA_COMMAND_CREATE_PLAYBACK_STREAM] = command_create_playback_stream, -+ [PA_COMMAND_CREATE_PLAYBACK_STREAM] = check_command_access, - [PA_COMMAND_DELETE_PLAYBACK_STREAM] = command_delete_stream, - [PA_COMMAND_DRAIN_PLAYBACK_STREAM] = command_drain_playback_stream, -- [PA_COMMAND_CREATE_RECORD_STREAM] = command_create_record_stream, -+ [PA_COMMAND_CREATE_RECORD_STREAM] = check_command_access, - [PA_COMMAND_DELETE_RECORD_STREAM] = command_delete_stream, - [PA_COMMAND_AUTH] = command_auth, - [PA_COMMAND_REQUEST] = NULL, -@@ -4865,10 +4948,10 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { - [PA_COMMAND_SET_CLIENT_NAME] = command_set_client_name, - [PA_COMMAND_LOOKUP_SINK] = command_lookup, - [PA_COMMAND_LOOKUP_SOURCE] = command_lookup, -- [PA_COMMAND_STAT] = command_stat, -+ [PA_COMMAND_STAT] = check_command_access, - [PA_COMMAND_GET_PLAYBACK_LATENCY] = command_get_playback_latency, - [PA_COMMAND_GET_RECORD_LATENCY] = command_get_record_latency, -- [PA_COMMAND_CREATE_UPLOAD_STREAM] = command_create_upload_stream, -+ [PA_COMMAND_CREATE_UPLOAD_STREAM] = check_command_access, - [PA_COMMAND_DELETE_UPLOAD_STREAM] = command_delete_stream, - [PA_COMMAND_FINISH_UPLOAD_STREAM] = command_finish_upload_stream, - [PA_COMMAND_PLAY_SAMPLE] = command_play_sample, --- -2.9.3 - diff --git a/0013-core-add-current_client.patch b/0013-core-add-current_client.patch deleted file mode 100644 index 425cc18..0000000 --- a/0013-core-add-current_client.patch +++ /dev/null @@ -1,249 +0,0 @@ -From 2c51c85d5c73b2217013a291cc80620e0b1ed268 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Fri, 27 Jan 2017 16:43:11 +0100 -Subject: [PATCH 13/18] core: add current_client - -Add the current client to the core object and configure it in the -various protocols whenever we start executing code for a pa_client. ---- - src/pulsecore/cli.c | 5 +++++ - src/pulsecore/core-struct.h | 2 ++ - src/pulsecore/core-subscribe.c | 4 ++++ - src/pulsecore/core.c | 10 ++++++++++ - src/pulsecore/core.h | 3 +++ - src/pulsecore/protocol-dbus.c | 5 +++++ - src/pulsecore/protocol-esound.c | 4 ++++ - src/pulsecore/protocol-http.c | 4 ++++ - src/pulsecore/protocol-native.c | 3 +++ - src/pulsecore/protocol-simple.c | 2 ++ - 10 files changed, 42 insertions(+) - -diff --git a/src/pulsecore/cli.c b/src/pulsecore/cli.c -index f942629..0546b06 100644 ---- a/src/pulsecore/cli.c -+++ b/src/pulsecore/cli.c -@@ -134,6 +134,8 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) { - return; - } - -+ pa_core_set_current_client(c->core, c->client); -+ - /* Magic command, like they had in AT Hayes Modems! Those were the good days! */ - if (pa_streq(s, "/")) - s = c->last_line; -@@ -151,10 +153,13 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) { - } - else - pa_cli_command_execute_line(c->core, s, buf, &c->fail); -+ - c->defer_kill--; - pa_ioline_puts(line, p = pa_strbuf_to_string_free(buf)); - pa_xfree(p); - -+ pa_core_set_current_client(c->core, NULL); -+ - if (c->kill_requested) { - if (c->eof_callback) - c->eof_callback(c, c->userdata); -diff --git a/src/pulsecore/core-struct.h b/src/pulsecore/core-struct.h -index e6aa374..8d58f1a 100644 ---- a/src/pulsecore/core-struct.h -+++ b/src/pulsecore/core-struct.h -@@ -98,6 +98,8 @@ struct pa_core { - pa_hook hooks[PA_CORE_HOOK_MAX]; - /* access hooks */ - pa_hook access[PA_ACCESS_HOOK_MAX]; -+ -+ pa_client *current_client; - }; - - #endif /* foocorestructhfoo */ -diff --git a/src/pulsecore/core-subscribe.c b/src/pulsecore/core-subscribe.c -index e60af21..a3f7ec7 100644 ---- a/src/pulsecore/core-subscribe.c -+++ b/src/pulsecore/core-subscribe.c -@@ -40,6 +40,7 @@ - - struct pa_subscription { - pa_core *core; -+ pa_client *client; - bool dead; - - pa_subscription_cb_t callback; -@@ -70,6 +71,7 @@ pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, pa_su - - s = pa_xnew(pa_subscription, 1); - s->core = c; -+ s->client = pa_core_get_current_client(c); - s->dead = false; - s->callback = callback; - s->userdata = userdata; -@@ -170,8 +172,10 @@ static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) { - for (s = c->subscriptions; s; s = s->next) { - - if (!s->dead && pa_subscription_match_flags(s->mask, e->type)) { -+ pa_core_set_current_client(c, s->client); - if (pa_core_check_access_sync(c, PA_ACCESS_HOOK_FILTER_SUBSCRIBE_EVENT, e->index, e->type, NULL)) - s->callback(c, e->type, e->index, s->userdata); -+ pa_core_set_current_client(c, NULL); - } - } - -diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c -index 6b9fb8b..311d31f 100644 ---- a/src/pulsecore/core.c -+++ b/src/pulsecore/core.c -@@ -154,6 +154,8 @@ pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t - for (j = 0; j < PA_ACCESS_HOOK_MAX; j++) - pa_hook_init(&c->access[j], c); - -+ c->current_client = NULL; -+ - pa_random(&c->cookie, sizeof(c->cookie)); - - #ifdef SIGPIPE -@@ -332,6 +334,14 @@ pa_mempool* pa_core_new_mempool(pa_core *c, pa_mem_type_t shm_type, bool per_cli - return pa_mempool_new(shm_type, c->shm_size, per_client); - } - -+pa_client* pa_core_get_current_client(pa_core *c) { -+ return c->current_client; -+} -+ -+void pa_core_set_current_client(pa_core *c, pa_client *client) { -+ c->current_client = client; -+} -+ - bool pa_core_check_access_sync(pa_core *c, pa_access_hook_t hook, uint32_t idx, pa_subscription_event_type_t event, const char *name) { - pa_access_data data; - -diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h -index 316a88e..42d1e11 100644 ---- a/src/pulsecore/core.h -+++ b/src/pulsecore/core.h -@@ -168,6 +168,9 @@ pa_mainloop_api* pa_core_get_mainloop(pa_core *c); - pa_mempool* pa_core_get_mempool(pa_core *c); - pa_mempool* pa_core_new_mempool(pa_core *c, pa_mem_type_t shm_type, bool per_client); - -+pa_client* pa_core_get_current_client(pa_core *c); -+void pa_core_set_current_client(pa_core *c, pa_client *client); -+ - pa_idxset* pa_core_get_modules(pa_core *c); - pa_idxset* pa_core_get_clients(pa_core *c); - pa_idxset* pa_core_get_cards(pa_core *c); -diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c -index 59afc1a..2ab0602 100644 ---- a/src/pulsecore/protocol-dbus.c -+++ b/src/pulsecore/protocol-dbus.c -@@ -494,6 +494,7 @@ static enum find_result_t find_handler(struct call_info *call_info) { - static DBusHandlerResult handle_message_cb(DBusConnection *connection, DBusMessage *message, void *user_data) { - pa_dbus_protocol *p = user_data; - struct call_info call_info; -+ pa_client *client; - - pa_assert(connection); - pa_assert(message); -@@ -520,6 +521,9 @@ static DBusHandlerResult handle_message_cb(DBusConnection *connection, DBusMessa - goto finish; - } - -+ client = pa_dbus_protocol_get_client(p, connection); -+ pa_core_set_current_client(p->core, client); -+ - switch (find_handler(&call_info)) { - case FOUND_GET_PROPERTY: - call_info.property_handler->get_cb(connection, message, call_info.iface_entry->userdata); -@@ -586,6 +590,7 @@ static DBusHandlerResult handle_message_cb(DBusConnection *connection, DBusMessa - default: - pa_assert_not_reached(); - } -+ pa_core_set_current_client(p->core, NULL); - - finish: - return DBUS_HANDLER_RESULT_HANDLED; -diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c -index 0d76525..706a21f 100644 ---- a/src/pulsecore/protocol-esound.c -+++ b/src/pulsecore/protocol-esound.c -@@ -1284,7 +1284,9 @@ static void io_callback(pa_iochannel*io, void *userdata) { - connection_assert_ref(c); - pa_assert(io); - -+ pa_core_set_current_client(c->protocol->core, c->client); - do_work(c); -+ pa_core_set_current_client(c->protocol->core, NULL); - } - - static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) { -@@ -1293,7 +1295,9 @@ static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) - connection_assert_ref(c); - pa_assert(e); - -+ pa_core_set_current_client(c->protocol->core, c->client); - do_work(c); -+ pa_core_set_current_client(c->protocol->core, NULL); - } - - static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { -diff --git a/src/pulsecore/protocol-http.c b/src/pulsecore/protocol-http.c -index 64024df..6fbd553 100644 ---- a/src/pulsecore/protocol-http.c -+++ b/src/pulsecore/protocol-http.c -@@ -647,6 +647,8 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) { - return; - } - -+ pa_core_set_current_client(c->protocol->core, c->client); -+ - switch (c->state) { - case STATE_REQUEST_LINE: { - if (pa_startswith(s, "GET ")) { -@@ -680,11 +682,13 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) { - default: - ; - } -+ pa_core_set_current_client(c->protocol->core, NULL); - - return; - - fail: - html_response(c, 500, "Internal Server Error", NULL); -+ pa_core_set_current_client(c->protocol->core, NULL); - } - - void pa_http_protocol_connect(pa_http_protocol *p, pa_iochannel *io, pa_module *m) { -diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c -index a866802..728c7e7 100644 ---- a/src/pulsecore/protocol-native.c -+++ b/src/pulsecore/protocol-native.c -@@ -5051,10 +5051,13 @@ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, pa_cmsg_an - pa_assert(packet); - pa_native_connection_assert_ref(c); - -+ pa_core_set_current_client(c->protocol->core, c->client); -+ - if (pa_pdispatch_run(c->pdispatch, packet, ancil_data, c) < 0) { - pa_log("invalid packet."); - native_connection_unlink(c); - } -+ pa_core_set_current_client(c->protocol->core, NULL); - } - - static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) { -diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c -index e1ead2f..8d4fbe4 100644 ---- a/src/pulsecore/protocol-simple.c -+++ b/src/pulsecore/protocol-simple.c -@@ -467,7 +467,9 @@ static void io_callback(pa_iochannel*io, void *userdata) { - connection_assert_ref(c); - pa_assert(io); - -+ pa_core_set_current_client(c->protocol->core, c->client); - do_work(c); -+ pa_core_set_current_client(c->protocol->core, NULL); - } - - /*** socket_server callbacks ***/ --- -2.9.3 - diff --git a/0014-core-ensure-maincontext-for-current-client.patch b/0014-core-ensure-maincontext-for-current-client.patch deleted file mode 100644 index 9a058ad..0000000 --- a/0014-core-ensure-maincontext-for-current-client.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 9820db2433a37aa1f22d962bb89876c66bcc1185 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Mon, 30 Jan 2017 11:52:54 +0100 -Subject: [PATCH 14/18] core: ensure maincontext for current client - -Make sure we can only access the current client from the main context. ---- - src/pulsecore/core.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c -index 311d31f..f14139f 100644 ---- a/src/pulsecore/core.c -+++ b/src/pulsecore/core.c -@@ -335,17 +335,20 @@ pa_mempool* pa_core_new_mempool(pa_core *c, pa_mem_type_t shm_type, bool per_cli - } - - pa_client* pa_core_get_current_client(pa_core *c) { -+ pa_assert_ctl_context(); - return c->current_client; - } - - void pa_core_set_current_client(pa_core *c, pa_client *client) { -- c->current_client = client; -+ pa_assert_ctl_context(); -+ c->current_client = client; - } - - bool pa_core_check_access_sync(pa_core *c, pa_access_hook_t hook, uint32_t idx, pa_subscription_event_type_t event, const char *name) { - pa_access_data data; - - pa_assert(c); -+ pa_assert_ctl_context(); - - if (c->current_client == NULL) - return true; -@@ -363,6 +366,7 @@ bool pa_core_check_access_sync(pa_core *c, pa_access_hook_t hook, uint32_t idx, - pa_hook_result_t pa_core_check_access(pa_core *c, pa_access_data *data) { - pa_assert(c); - pa_assert(data); -+ pa_assert_ctl_context(); - - if (c->current_client == NULL) - return PA_HOOK_OK; --- -2.9.3 - diff --git a/0015-Add-flatpak-access-control.patch b/0015-Add-flatpak-access-control.patch deleted file mode 100644 index 1fcbff7..0000000 --- a/0015-Add-flatpak-access-control.patch +++ /dev/null @@ -1,828 +0,0 @@ -From 46754adc0e09e7ea8a9c84183425924333c0d251 Mon Sep 17 00:00:00 2001 -From: Matthias Clasen -Date: Fri, 15 Jul 2016 09:55:44 -0400 -Subject: [PATCH 15/18] Add flatpak access control - -Add a module that talks to xdg-desktop-portal for access control -in sandboxed applications. Currently, it asks the portal for -access to microphone/speakers when a record or playback stream -is opened or samples are played. - -For non-sandboxed applications, the module imposes no restrictions. ---- - src/Makefile.am | 9 +- - src/modules/module-access.c | 4 +- - src/modules/module-flatpak.c | 738 +++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 749 insertions(+), 2 deletions(-) - create mode 100644 src/modules/module-flatpak.c - -diff --git a/src/Makefile.am b/src/Makefile.am -index 70bc848..0e0a480 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -1175,7 +1175,8 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMIN - if HAVE_DBUS - # Serveral module (e.g. libalsa-util.la) - modlibexec_LTLIBRARIES += \ -- module-console-kit.la -+ module-console-kit.la \ -+ module-flatpak.la - endif - - modlibexec_LTLIBRARIES += \ -@@ -1473,6 +1474,7 @@ endif - # These are generated by an M4 script - SYMDEF_FILES = \ - module-access-symdef.h \ -+ module-flatpak-symdef.h \ - module-cli-symdef.h \ - module-cli-protocol-tcp-symdef.h \ - module-cli-protocol-unix-symdef.h \ -@@ -1600,6 +1602,11 @@ module_access_la_SOURCES = modules/module-access.c - module_access_la_LDFLAGS = $(MODULE_LDFLAGS) - module_access_la_LIBADD = $(MODULE_LIBADD) - -+module_flatpak_la_SOURCES = modules/module-flatpak.c -+module_flatpak_la_CFLAGS = $(AM_CDFLAGS) $(DBUS_CFLAGS) -+module_flatpak_la_LDFLAGS = $(MODULE_LDFLAGS) -+module_flatpak_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) -+ - # CLI protocol - - module_cli_la_SOURCES = modules/module-cli.c -diff --git a/src/modules/module-access.c b/src/modules/module-access.c -index 39e2f0e..dec1dbf 100644 ---- a/src/modules/module-access.c -+++ b/src/modules/module-access.c -@@ -498,9 +498,9 @@ int pa__init(pa_module*m) { - ap->rule[PA_ACCESS_HOOK_VIEW_CARD] = rule_allow; - ap->rule[PA_ACCESS_HOOK_STAT] = rule_allow; - ap->rule[PA_ACCESS_HOOK_VIEW_SAMPLE] = rule_allow; -+ - ap->rule[PA_ACCESS_HOOK_PLAY_SAMPLE] = rule_allow; - ap->rule[PA_ACCESS_HOOK_CONNECT_PLAYBACK] = rule_allow; -- - ap->rule[PA_ACCESS_HOOK_CONNECT_RECORD] = rule_check_async; - - ap->rule[PA_ACCESS_HOOK_VIEW_CLIENT] = rule_check_owner; -@@ -508,11 +508,13 @@ int pa__init(pa_module*m) { - - ap->rule[PA_ACCESS_HOOK_CREATE_SINK_INPUT] = rule_allow; - ap->rule[PA_ACCESS_HOOK_VIEW_SINK_INPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_MOVE_SINK_INPUT] = rule_check_owner; - ap->rule[PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME] = rule_check_owner; - ap->rule[PA_ACCESS_HOOK_KILL_SINK_INPUT] = rule_check_owner; - - ap->rule[PA_ACCESS_HOOK_CREATE_SOURCE_OUTPUT] = rule_allow; - ap->rule[PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_MOVE_SOURCE_OUTPUT] = rule_check_owner; - ap->rule[PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME] = rule_check_owner; - ap->rule[PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT] = rule_check_owner; - -diff --git a/src/modules/module-flatpak.c b/src/modules/module-flatpak.c -new file mode 100644 -index 0000000..64bbe86 ---- /dev/null -+++ b/src/modules/module-flatpak.c -@@ -0,0 +1,738 @@ -+/*** -+ This file is part of PulseAudio. -+ -+ Copyright 2016 Red Hat, Inc. -+ -+ PulseAudio 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.1 of the License, -+ or (at your option) any later version. -+ -+ PulseAudio 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 -+ General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with PulseAudio; if not, see . -+***/ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "module-access-symdef.h" -+ -+PA_MODULE_AUTHOR("Matthias Clasen"); -+PA_MODULE_DESCRIPTION("Controls access to server resources for flatpak apps"); -+PA_MODULE_VERSION(PACKAGE_VERSION); -+PA_MODULE_LOAD_ONCE(true); -+PA_MODULE_USAGE(""); -+ -+static const char* const valid_modargs[] = { -+ NULL, -+}; -+ -+typedef struct access_policy access_policy; -+typedef struct event_item event_item; -+typedef struct client_data client_data; -+typedef struct userdata userdata; -+ -+typedef pa_hook_result_t (*access_rule_t)(pa_core *c, pa_access_data *d, struct userdata *u); -+ -+struct access_policy { -+ uint32_t index; -+ struct userdata *userdata; -+ -+ access_rule_t rule[PA_ACCESS_HOOK_MAX]; -+}; -+ -+struct event_item { -+ PA_LLIST_FIELDS(event_item); -+ -+ int facility; -+ uint32_t object_index; -+}; -+ -+struct async_cache { -+ bool checked; -+ bool granted; -+}; -+ -+struct userdata { -+ pa_core *core; -+ -+ pa_hook_slot *hook[PA_ACCESS_HOOK_MAX]; -+ -+ pa_idxset *policies; -+ uint32_t default_policy; -+ uint32_t portal_policy; -+ -+ pa_dbus_connection *connection; -+ pa_hashmap *clients; -+ pa_hook_slot *client_put_slot; -+ pa_hook_slot *client_auth_slot; -+ pa_hook_slot *client_proplist_changed_slot; -+ pa_hook_slot *client_unlink_slot; -+}; -+ -+struct client_data { -+ struct userdata *u; -+ -+ uint32_t index; -+ uint32_t policy; -+ pid_t pid; -+ -+ struct async_cache cached[PA_ACCESS_HOOK_MAX]; -+ pa_access_data *access_data; -+ -+ PA_LLIST_HEAD(event_item, events); -+}; -+ -+ -+static void add_event(struct client_data *cd, int facility, uint32_t oidx) { -+ event_item *i; -+ -+ i = pa_xnew0(event_item, 1); -+ PA_LLIST_INIT(event_item, i); -+ i->facility = facility; -+ i->object_index = oidx; -+ -+ PA_LLIST_PREPEND(event_item, cd->events, i); -+} -+ -+static event_item *find_event(struct client_data *cd, int facility, uint32_t oidx) { -+ event_item *i; -+ -+ PA_LLIST_FOREACH(i, cd->events) { -+ if (i->facility == facility && i->object_index == oidx) -+ return i; -+ } -+ return NULL; -+} -+ -+static bool remove_event(struct client_data *cd, int facility, uint32_t oidx) { -+ event_item *i = find_event(cd, facility, oidx); -+ if (i) { -+ PA_LLIST_REMOVE(event_item, cd->events, i); -+ pa_xfree(i); -+ return true; -+ } -+ return false; -+} -+ -+static client_data * client_data_new(struct userdata *u, uint32_t index, uint32_t policy, pid_t pid) { -+ client_data *cd; -+ -+ cd = pa_xnew0(client_data, 1); -+ cd->u = u; -+ cd->index = index; -+ cd->policy = policy; -+ cd->pid = pid; -+ pa_hashmap_put(u->clients, PA_UINT32_TO_PTR(index), cd); -+ pa_log("new client %d with pid %d, policy %d", index, pid, policy); -+ -+ return cd; -+} -+ -+static void client_data_free(client_data *cd) { -+ event_item *e; -+ -+ while ((e = cd->events)) { -+ PA_LLIST_REMOVE(event_item, cd->events, e); -+ pa_xfree(e); -+ } -+ pa_log("removed client %d", cd->index); -+ pa_xfree(cd); -+} -+ -+static client_data * client_data_get(struct userdata *u, uint32_t index) { -+ return pa_hashmap_get(u->clients, PA_UINT32_TO_PTR(index)); -+} -+ -+static void client_data_remove(struct userdata *u, uint32_t index) { -+ pa_hashmap_remove_and_free(u->clients, PA_UINT32_TO_PTR(index)); -+} -+ -+/* rule checks if the operation on the object is performed by the owner of the object */ -+static pa_hook_result_t rule_check_owner (pa_core *c, pa_access_data *d, struct userdata *u) { -+ pa_hook_result_t result = PA_HOOK_STOP; -+ uint32_t idx = PA_INVALID_INDEX; -+ -+ switch (d->hook) { -+ case PA_ACCESS_HOOK_VIEW_CLIENT: -+ case PA_ACCESS_HOOK_KILL_CLIENT: { -+ idx = d->object_index; -+ break; -+ } -+ -+ case PA_ACCESS_HOOK_VIEW_SINK_INPUT: -+ case PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME: -+ case PA_ACCESS_HOOK_KILL_SINK_INPUT: { -+ const pa_sink_input *si = pa_idxset_get_by_index(c->sink_inputs, d->object_index); -+ idx = (si && si->client) ? si->client->index : PA_INVALID_INDEX; -+ break; -+ } -+ -+ case PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT: -+ case PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME: -+ case PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT: { -+ const pa_source_output *so = pa_idxset_get_by_index(c->source_outputs, d->object_index); -+ idx = (so && so->client) ? so->client->index : PA_INVALID_INDEX; -+ break; -+ } -+ default: -+ break; -+ } -+ if (idx == d->client_index) { -+ pa_log("allow operation %d/%d of same client %d", d->hook, d->object_index, idx); -+ result = PA_HOOK_OK; -+ } else -+ pa_log("blocked operation %d/%d of client %d to client %d", d->hook, d->object_index, idx, d->client_index); -+ -+ return result; -+} -+ -+/* rule allows the operation */ -+static pa_hook_result_t rule_allow (pa_core *c, pa_access_data *d, struct userdata *u) { -+ pa_log("allow operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ return PA_HOOK_OK; -+} -+ -+/* rule blocks the operation */ -+static pa_hook_result_t rule_block (pa_core *c, pa_access_data *d, struct userdata *u) { -+ pa_log("blocked operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ return PA_HOOK_STOP; -+} -+ -+static DBusHandlerResult portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data) -+{ -+ client_data *cd = user_data; -+ pa_access_data *d = cd->access_data; -+ -+ if (dbus_message_is_signal(msg, "org.freedesktop.portal.Request", "Response")) { -+ uint32_t response = 2; -+ DBusError error; -+ -+ dbus_error_init(&error); -+ -+ dbus_connection_remove_filter (connection, portal_response, cd); -+ -+ if (!dbus_message_get_args(msg, &error, DBUS_TYPE_UINT32, &response, DBUS_TYPE_INVALID)) { -+ pa_log("failed to parse Response: %s\n", error.message); -+ dbus_error_free(&error); -+ } -+ -+ cd->cached[d->hook].checked = true; -+ cd->cached[d->hook].granted = response == 0 ? true : false; -+ -+ pa_log("portal check result: %d\n", cd->cached[d->hook].granted); -+ -+ d->complete_cb (d, cd->cached[d->hook].granted); -+ -+ return DBUS_HANDLER_RESULT_HANDLED; -+ } -+ -+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -+} -+ -+static pa_hook_result_t rule_check_portal (pa_core *c, pa_access_data *d, struct userdata *u) { -+ client_data *cd = client_data_get(u, d->client_index); -+ DBusMessage *m = NULL, *r = NULL; -+ DBusError error; -+ pid_t pid; -+ DBusMessageIter msg_iter; -+ DBusMessageIter dict_iter; -+ const char *handle; -+ const char *device; -+ -+ if (cd->cached[d->hook].checked) { -+ pa_log("returned cached answer for portal check: %d\n", cd->cached[d->hook].granted); -+ return cd->cached[d->hook].granted ? PA_HOOK_OK : PA_HOOK_STOP; -+ } -+ -+ pa_log("ask portal for operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ -+ cd->access_data = d; -+ -+ dbus_error_init(&error); -+ -+ if (!(m = dbus_message_new_method_call("org.freedesktop.portal.Desktop", -+ "/org/freedesktop/portal/desktop", -+ "org.freedesktop.portal.Device", -+ "AccessDevice"))) { -+ return PA_HOOK_STOP; -+ } -+ -+ if (d->hook == PA_ACCESS_HOOK_CONNECT_RECORD) -+ device = "microphone"; -+ else if (d->hook == PA_ACCESS_HOOK_CONNECT_PLAYBACK || -+ d->hook == PA_ACCESS_HOOK_PLAY_SAMPLE) -+ device = "speakers"; -+ else -+ pa_assert_not_reached (); -+ -+ pid = cd->pid; -+ if (!dbus_message_append_args(m, -+ DBUS_TYPE_UINT32, &pid, -+ DBUS_TYPE_INVALID)) { -+ dbus_message_unref(m); -+ return PA_HOOK_STOP; -+ } -+ -+ dbus_message_iter_init_append(m, &msg_iter); -+ dbus_message_iter_open_container (&msg_iter, DBUS_TYPE_ARRAY, "s", &dict_iter); -+ dbus_message_iter_append_basic (&dict_iter, DBUS_TYPE_STRING, &device); -+ dbus_message_iter_close_container (&msg_iter, &dict_iter); -+ -+ dbus_message_iter_open_container (&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter); -+ dbus_message_iter_close_container (&msg_iter, &dict_iter); -+ -+ if (!(r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(u->connection), m, -1, &error))) { -+ pa_log("Failed to call portal: %s\n", error.message); -+ dbus_error_free(&error); -+ dbus_message_unref(m); -+ return PA_HOOK_STOP; -+ } -+ -+ dbus_message_unref(m); -+ -+ if (!dbus_message_get_args(r, &error, DBUS_TYPE_OBJECT_PATH, &handle, DBUS_TYPE_INVALID)) { -+ pa_log("Failed to parse AccessDevice result: %s\n", error.message); -+ dbus_error_free(&error); -+ dbus_message_unref(r); -+ return PA_HOOK_STOP; -+ } -+ -+ dbus_message_unref(r); -+ -+ dbus_bus_add_match(pa_dbus_connection_get(u->connection), -+ "type='signal',interface='org.freedesktop.portal.Request'", -+ &error); -+ dbus_connection_flush(pa_dbus_connection_get(u->connection)); -+ if (dbus_error_is_set(&error)) { -+ pa_log("Failed to subscribe to Request signal: %s\n", error.message); -+ dbus_error_free(&error); -+ return PA_HOOK_STOP; -+ } -+ -+ dbus_connection_add_filter(pa_dbus_connection_get(u->connection), portal_response, cd, NULL); -+ -+ return PA_HOOK_CANCEL; -+} -+ -+static access_policy *access_policy_new(struct userdata *u, bool allow_all) { -+ access_policy *ap; -+ int i; -+ -+ ap = pa_xnew0(access_policy, 1); -+ ap->userdata = u; -+ for (i = 0; i < PA_ACCESS_HOOK_MAX; i++) -+ ap->rule[i] = allow_all ? rule_allow : rule_block; -+ -+ pa_idxset_put(u->policies, ap, &ap->index); -+ -+ return ap; -+} -+ -+static void access_policy_free(access_policy *ap) { -+ pa_idxset_remove_by_index(ap->userdata->policies, ap->index); -+ pa_xfree(ap); -+} -+ -+static pa_hook_result_t check_access (pa_core *c, pa_access_data *d, struct userdata *u) { -+ access_policy *ap; -+ access_rule_t rule; -+ client_data *cd = client_data_get(u, d->client_index); -+ -+ /* unknown client */ -+ if (cd == NULL) -+ return PA_HOOK_STOP; -+ -+ ap = pa_idxset_get_by_index(u->policies, cd->policy); -+ -+ rule = ap->rule[d->hook]; -+ if (rule) -+ return rule(c, d, u); -+ -+ return PA_HOOK_STOP; -+} -+ -+static const pa_access_hook_t event_hook[PA_SUBSCRIPTION_EVENT_FACILITY_MASK+1] = { -+ [PA_SUBSCRIPTION_EVENT_SINK] = PA_ACCESS_HOOK_VIEW_SINK, -+ [PA_SUBSCRIPTION_EVENT_SOURCE] = PA_ACCESS_HOOK_VIEW_SOURCE, -+ [PA_SUBSCRIPTION_EVENT_SINK_INPUT] = PA_ACCESS_HOOK_VIEW_SINK_INPUT, -+ [PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT] = PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT, -+ [PA_SUBSCRIPTION_EVENT_MODULE] = PA_ACCESS_HOOK_VIEW_MODULE, -+ [PA_SUBSCRIPTION_EVENT_CLIENT] = PA_ACCESS_HOOK_VIEW_CLIENT, -+ [PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE] = PA_ACCESS_HOOK_VIEW_SAMPLE, -+ [PA_SUBSCRIPTION_EVENT_SERVER] = PA_ACCESS_HOOK_VIEW_SERVER, -+ [PA_SUBSCRIPTION_EVENT_CARD] = PA_ACCESS_HOOK_VIEW_CARD -+}; -+ -+static pa_hook_result_t filter_event (pa_core *c, pa_access_data *d, struct userdata *u) { -+ int facility; -+ client_data *cd; -+ -+ facility = d->event & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; -+ -+ cd = client_data_get (u, d->client_index); -+ /* unknown client destination, block event */ -+ if (cd == NULL) -+ goto block; -+ -+ switch (d->event & PA_SUBSCRIPTION_EVENT_TYPE_MASK) { -+ case PA_SUBSCRIPTION_EVENT_REMOVE: -+ /* if the client saw this object before, let the event go through */ -+ if (remove_event(cd, facility, d->object_index)) { -+ pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ return PA_HOOK_OK; -+ } -+ break; -+ -+ case PA_SUBSCRIPTION_EVENT_CHANGE: -+ /* if the client saw this object before, let it go through */ -+ if (find_event(cd, facility, d->object_index)) { -+ pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ return PA_HOOK_OK; -+ } -+ -+ /* fallthrough to do hook check and register event */ -+ case PA_SUBSCRIPTION_EVENT_NEW: { -+ pa_access_data data = *d; -+ -+ /* new object, check if the client is allowed to inspect it */ -+ data.hook = event_hook[facility]; -+ if (data.hook && pa_hook_fire(&c->access[data.hook], &data) == PA_HOOK_OK) { -+ /* client can inspect the object, remember for later */ -+ add_event(cd, facility, d->object_index); -+ pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ return PA_HOOK_OK; -+ } -+ break; -+ } -+ default: -+ break; -+ } -+ -+block: -+ pa_log("blocked event %02x/%d for client %d", d->event, d->object_index, d->client_index); -+ return PA_HOOK_STOP; -+} -+ -+static bool -+client_is_sandboxed (pa_client *cl) -+{ -+ char *path; -+ char data[2048]; -+ int n; -+ const char *state = NULL; -+ const char *current; -+ bool result; -+ int fd; -+ pid_t pid; -+ -+ if (cl->creds_valid) { -+ pa_log ("client has trusted pid %d", cl->creds.pid); -+ } -+ else { -+ pa_log ("no trusted pid found, assuming not sandboxed\n"); -+ return false; -+ } -+ -+ pid = cl->creds.pid; -+ -+ path = pa_sprintf_malloc("/proc/%u/cgroup", pid); -+ fd = pa_open_cloexec(path, O_RDONLY, 0); -+ free (path); -+ -+ if (fd == -1) -+ return false; -+ -+ pa_loop_read(fd, &data, sizeof(data), NULL); -+ close(fd); -+ -+ result = false; -+ while ((current = pa_split_in_place(data, "\n", &n, &state)) != NULL) { -+ if (strncmp(current, "1:name=systemd:", strlen("1:name=systemd:")) == 0) { -+ const char *p = strstr(current, "flatpak-"); -+ if (p && p - current < n) { -+ pa_log("found a flatpak cgroup, assuming sandboxed\n"); -+ result = true; -+ break; -+ } -+ } -+ } -+ -+ return result; -+} -+ -+static uint32_t find_policy_for_client (struct userdata *u, pa_client *cl) { -+ char *s; -+ -+ s = pa_proplist_to_string(cl->proplist); -+ pa_log ("client proplist %s", s); -+ pa_xfree(s); -+ -+ if (client_is_sandboxed (cl)) { -+ pa_log("client is sandboxed, choosing portal policy\n"); -+ return u->portal_policy; -+ } -+ else { -+ pa_log("client not sandboxed, choosing default policy\n"); -+ return u->default_policy; -+ } -+} -+ -+static pa_hook_result_t client_put_cb(pa_core *c, pa_object *o, struct userdata *u) { -+ pa_client *cl; -+ uint32_t policy; -+ -+pa_log("client put\n"); -+ pa_assert(c); -+ pa_object_assert_ref(o); -+ -+ cl = (pa_client *) o; -+ pa_assert(cl); -+ -+ /* when we get here, the client just connected and is not yet authenticated -+ * we should probably install a policy that denies all access */ -+ policy = find_policy_for_client(u, cl); -+ -+ client_data_new(u, cl->index, policy, cl->creds.pid); -+ -+ return PA_HOOK_OK; -+} -+ -+static pa_hook_result_t client_auth_cb(pa_core *c, pa_object *o, struct userdata *u) { -+ pa_client *cl; -+ client_data *cd; -+ uint32_t policy; -+ -+ pa_assert(c); -+ pa_object_assert_ref(o); -+ -+ cl = (pa_client *) o; -+ pa_assert(cl); -+ -+ cd = client_data_get (u, cl->index); -+ if (cd == NULL) -+ return PA_HOOK_OK; -+ -+ policy = find_policy_for_client(u, cl); -+ cd->policy = policy; -+ -+ return PA_HOOK_OK; -+} -+ -+static pa_hook_result_t client_proplist_changed_cb(pa_core *c, pa_object *o, struct userdata *u) { -+ pa_client *cl; -+ client_data *cd; -+ uint32_t policy; -+ -+ pa_assert(c); -+ pa_object_assert_ref(o); -+ -+ cl = (pa_client *) o; -+ pa_assert(cl); -+ -+ cd = client_data_get (u, cl->index); -+ if (cd == NULL) -+ return PA_HOOK_OK; -+ -+ policy = find_policy_for_client(u, cl); -+ cd->policy = policy; -+ cd->pid = cl->creds.pid; -+ -+ return PA_HOOK_OK; -+} -+ -+static pa_hook_result_t client_unlink_cb(pa_core *c, pa_object *o, struct userdata *u) { -+ pa_client *cl; -+ -+ pa_assert(c); -+ pa_object_assert_ref(o); -+ -+ cl = (pa_client *) o; -+ pa_assert(cl); -+ -+ client_data_remove(u, cl->index); -+ -+ return PA_HOOK_OK; -+} -+ -+ -+int pa__init(pa_module*m) { -+ pa_modargs *ma = NULL; -+ struct userdata *u; -+ int i; -+ access_policy *ap; -+ DBusError error; -+ -+ pa_assert(m); -+ -+ if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { -+ pa_log("Failed to parse module arguments"); -+ goto fail; -+ } -+ -+ u = pa_xnew0(struct userdata, 1); -+ u->core = m->core; -+ m->userdata = u; -+ -+ dbus_error_init(&error); -+ -+ if (!(u->connection = pa_dbus_bus_get (u->core, DBUS_BUS_SESSION, &error))) { -+ pa_log("Failed to connect to session bus: %s\n", error.message); -+ dbus_error_free(&error); -+ } -+ -+ u->policies = pa_idxset_new (NULL, NULL); -+ u->clients = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, -+ (pa_free_cb_t) client_data_free); -+ -+ u->client_put_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) client_put_cb, u); -+ u->client_auth_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_AUTH], PA_HOOK_EARLY, (pa_hook_cb_t) client_auth_cb, u); -+ u->client_proplist_changed_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) client_proplist_changed_cb, u); -+ u->client_unlink_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_CLIENT_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) client_unlink_cb, u); -+ -+ for (i = 0; i < PA_ACCESS_HOOK_MAX; i++) { -+ pa_hook_cb_t cb; -+ -+ if (i == PA_ACCESS_HOOK_FILTER_SUBSCRIBE_EVENT) -+ cb = (pa_hook_cb_t) filter_event; -+ else -+ cb = (pa_hook_cb_t) check_access; -+ -+ u->hook[i] = pa_hook_connect(&u->core->access[i], PA_HOOK_EARLY - 1, cb, u); -+ } -+ -+ ap = access_policy_new(u, false); -+ -+ ap->rule[PA_ACCESS_HOOK_VIEW_SINK] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SOURCE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SERVER] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_MODULE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_CARD] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_STAT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SAMPLE] = rule_allow; -+ -+ ap->rule[PA_ACCESS_HOOK_PLAY_SAMPLE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_CONNECT_PLAYBACK] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_CONNECT_RECORD] = rule_allow; -+ -+ ap->rule[PA_ACCESS_HOOK_VIEW_CLIENT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_KILL_CLIENT] = rule_check_owner; -+ -+ ap->rule[PA_ACCESS_HOOK_CREATE_SINK_INPUT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SINK_INPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_MOVE_SINK_INPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_KILL_SINK_INPUT] = rule_check_owner; -+ -+ ap->rule[PA_ACCESS_HOOK_CREATE_SOURCE_OUTPUT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_MOVE_SOURCE_OUTPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT] = rule_check_owner; -+ -+ u->default_policy = ap->index; -+ -+ ap = access_policy_new(u, false); -+ -+ ap->rule[PA_ACCESS_HOOK_VIEW_SINK] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SOURCE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SERVER] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_MODULE] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_CARD] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_STAT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SAMPLE] = rule_allow; -+ -+ ap->rule[PA_ACCESS_HOOK_PLAY_SAMPLE] = rule_check_portal; -+ ap->rule[PA_ACCESS_HOOK_CONNECT_PLAYBACK] = rule_check_portal; -+ ap->rule[PA_ACCESS_HOOK_CONNECT_RECORD] = rule_check_portal; -+ -+ ap->rule[PA_ACCESS_HOOK_VIEW_CLIENT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_KILL_CLIENT] = rule_check_owner; -+ -+ ap->rule[PA_ACCESS_HOOK_CREATE_SINK_INPUT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SINK_INPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_MOVE_SINK_INPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_SET_SINK_INPUT_VOLUME] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_KILL_SINK_INPUT] = rule_check_owner; -+ -+ ap->rule[PA_ACCESS_HOOK_CREATE_SOURCE_OUTPUT] = rule_allow; -+ ap->rule[PA_ACCESS_HOOK_VIEW_SOURCE_OUTPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_MOVE_SOURCE_OUTPUT] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME] = rule_check_owner; -+ ap->rule[PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT] = rule_check_owner; -+ -+ u->portal_policy = ap->index; -+ -+ pa_modargs_free(ma); -+ return 0; -+ -+fail: -+ pa__done(m); -+ -+ if (ma) -+ pa_modargs_free(ma); -+ return -1; -+} -+ -+void pa__done(pa_module*m) { -+ struct userdata* u; -+ int i; -+ -+ pa_assert(m); -+ -+ if (!(u = m->userdata)) -+ return; -+ -+ for (i = 0; i < PA_ACCESS_HOOK_MAX; i++) { -+ if (u->hook[i]) -+ pa_hook_slot_free(u->hook[i]); -+ } -+ -+ if (u->policies) -+ pa_idxset_free(u->policies, (pa_free_cb_t) access_policy_free); -+ -+ if (u->client_put_slot) -+ pa_hook_slot_free(u->client_put_slot); -+ if (u->client_auth_slot) -+ pa_hook_slot_free(u->client_auth_slot); -+ if (u->client_proplist_changed_slot) -+ pa_hook_slot_free(u->client_proplist_changed_slot); -+ if (u->client_unlink_slot) -+ pa_hook_slot_free(u->client_unlink_slot); -+ -+ if (u->clients) -+ pa_hashmap_free(u->clients); -+ -+ if (u->connection) -+ pa_dbus_connection_unref (u->connection); -+ -+ pa_xfree(u); -+} --- -2.9.3 - diff --git a/0016-Make-flatpak-module-load.patch b/0016-Make-flatpak-module-load.patch deleted file mode 100644 index 7c034ed..0000000 --- a/0016-Make-flatpak-module-load.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 161ed876c3c810cb2de47516e11cf632591174bd Mon Sep 17 00:00:00 2001 -From: Matthias Clasen -Date: Fri, 15 Jul 2016 15:10:20 -0400 -Subject: [PATCH 16/18] Make flatpak module load - -It was using the wrong symver header. ---- - src/modules/module-flatpak.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/modules/module-flatpak.c b/src/modules/module-flatpak.c -index 64bbe86..cf428d4 100644 ---- a/src/modules/module-flatpak.c -+++ b/src/modules/module-flatpak.c -@@ -43,7 +43,7 @@ - #include - #include - --#include "module-access-symdef.h" -+#include "module-flatpak-symdef.h" - - PA_MODULE_AUTHOR("Matthias Clasen"); - PA_MODULE_DESCRIPTION("Controls access to server resources for flatpak apps"); --- -2.9.3 - diff --git a/0017-Make-sure-to-set-the-pid-in-auth_cb.patch b/0017-Make-sure-to-set-the-pid-in-auth_cb.patch deleted file mode 100644 index 8e1f413..0000000 --- a/0017-Make-sure-to-set-the-pid-in-auth_cb.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 6fc7131ec231865d2c1ce8267013d9cf78f36e68 Mon Sep 17 00:00:00 2001 -From: Matthias Clasen -Date: Fri, 15 Jul 2016 16:05:36 -0400 -Subject: [PATCH 17/18] Make sure to set the pid in auth_cb - ---- - src/modules/module-flatpak.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/modules/module-flatpak.c b/src/modules/module-flatpak.c -index cf428d4..9375a9b 100644 ---- a/src/modules/module-flatpak.c -+++ b/src/modules/module-flatpak.c -@@ -510,7 +510,6 @@ static pa_hook_result_t client_put_cb(pa_core *c, pa_object *o, struct userdata - pa_client *cl; - uint32_t policy; - --pa_log("client put\n"); - pa_assert(c); - pa_object_assert_ref(o); - -@@ -523,6 +522,8 @@ pa_log("client put\n"); - - client_data_new(u, cl->index, policy, cl->creds.pid); - -+ pa_log("client put: policy %d, pid %u\n", policy, cl->creds.pid); -+ - return PA_HOOK_OK; - } - -@@ -543,6 +544,9 @@ static pa_hook_result_t client_auth_cb(pa_core *c, pa_object *o, struct userdata - - policy = find_policy_for_client(u, cl); - cd->policy = policy; -+ cd->pid = cl->creds.pid; -+ -+ pa_log("auth cb: policy %d, pid %u\n", cd->policy, cd->pid); - - return PA_HOOK_OK; - } --- -2.9.3 - diff --git a/0018-Use-permissive-policy-by-default.patch b/0018-Use-permissive-policy-by-default.patch deleted file mode 100644 index 41948ae..0000000 --- a/0018-Use-permissive-policy-by-default.patch +++ /dev/null @@ -1,278 +0,0 @@ -From e323416499a5c6c5b5261eabb59c5e6a7ffdc300 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Mon, 13 Feb 2017 10:42:36 +0100 -Subject: [PATCH 18/18] Use permissive policy by default - -Make a default permissive policy that allows everything when not -sandboxed. -Improve debug log ---- - src/modules/module-flatpak.c | 69 ++++++++++++++++++++++---------------------- - 1 file changed, 35 insertions(+), 34 deletions(-) - -diff --git a/src/modules/module-flatpak.c b/src/modules/module-flatpak.c -index 9375a9b..b223279 100644 ---- a/src/modules/module-flatpak.c -+++ b/src/modules/module-flatpak.c -@@ -87,8 +87,10 @@ struct userdata { - pa_hook_slot *hook[PA_ACCESS_HOOK_MAX]; - - pa_idxset *policies; -- uint32_t default_policy; -+ uint32_t permissive_policy; -+ uint32_t restricted_policy; - uint32_t portal_policy; -+ uint32_t default_policy; - - pa_dbus_connection *connection; - pa_hashmap *clients; -@@ -152,7 +154,7 @@ static client_data * client_data_new(struct userdata *u, uint32_t index, uint32_ - cd->policy = policy; - cd->pid = pid; - pa_hashmap_put(u->clients, PA_UINT32_TO_PTR(index), cd); -- pa_log("new client %d with pid %d, policy %d", index, pid, policy); -+ pa_log_debug("new client %d with pid %d, policy %d", index, pid, policy); - - return cd; - } -@@ -164,7 +166,7 @@ static void client_data_free(client_data *cd) { - PA_LLIST_REMOVE(event_item, cd->events, e); - pa_xfree(e); - } -- pa_log("removed client %d", cd->index); -+ pa_log_debug("removed client %d", cd->index); - pa_xfree(cd); - } - -@@ -207,23 +209,23 @@ static pa_hook_result_t rule_check_owner (pa_core *c, pa_access_data *d, struct - break; - } - if (idx == d->client_index) { -- pa_log("allow operation %d/%d of same client %d", d->hook, d->object_index, idx); -+ pa_log_debug("allow operation %d/%d of same client %d", d->hook, d->object_index, idx); - result = PA_HOOK_OK; - } else -- pa_log("blocked operation %d/%d of client %d to client %d", d->hook, d->object_index, idx, d->client_index); -+ pa_log_debug("blocked operation %d/%d of client %d to client %d", d->hook, d->object_index, idx, d->client_index); - - return result; - } - - /* rule allows the operation */ - static pa_hook_result_t rule_allow (pa_core *c, pa_access_data *d, struct userdata *u) { -- pa_log("allow operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ pa_log_debug("allow operation %d/%d for client %d", d->hook, d->object_index, d->client_index); - return PA_HOOK_OK; - } - - /* rule blocks the operation */ - static pa_hook_result_t rule_block (pa_core *c, pa_access_data *d, struct userdata *u) { -- pa_log("blocked operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ pa_log_debug("blocked operation %d/%d for client %d", d->hook, d->object_index, d->client_index); - return PA_HOOK_STOP; - } - -@@ -241,14 +243,14 @@ static DBusHandlerResult portal_response(DBusConnection *connection, DBusMessage - dbus_connection_remove_filter (connection, portal_response, cd); - - if (!dbus_message_get_args(msg, &error, DBUS_TYPE_UINT32, &response, DBUS_TYPE_INVALID)) { -- pa_log("failed to parse Response: %s\n", error.message); -+ pa_log_error("failed to parse Response: %s\n", error.message); - dbus_error_free(&error); - } - - cd->cached[d->hook].checked = true; - cd->cached[d->hook].granted = response == 0 ? true : false; - -- pa_log("portal check result: %d\n", cd->cached[d->hook].granted); -+ pa_log_debug("portal check result: %d\n", cd->cached[d->hook].granted); - - d->complete_cb (d, cd->cached[d->hook].granted); - -@@ -269,11 +271,11 @@ static pa_hook_result_t rule_check_portal (pa_core *c, pa_access_data *d, struct - const char *device; - - if (cd->cached[d->hook].checked) { -- pa_log("returned cached answer for portal check: %d\n", cd->cached[d->hook].granted); -+ pa_log_debug("returned cached answer for portal check: %d\n", cd->cached[d->hook].granted); - return cd->cached[d->hook].granted ? PA_HOOK_OK : PA_HOOK_STOP; - } - -- pa_log("ask portal for operation %d/%d for client %d", d->hook, d->object_index, d->client_index); -+ pa_log_info("ask portal for operation %d/%d for client %d", d->hook, d->object_index, d->client_index); - - cd->access_data = d; - -@@ -311,7 +313,7 @@ static pa_hook_result_t rule_check_portal (pa_core *c, pa_access_data *d, struct - dbus_message_iter_close_container (&msg_iter, &dict_iter); - - if (!(r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(u->connection), m, -1, &error))) { -- pa_log("Failed to call portal: %s\n", error.message); -+ pa_log_error("Failed to call portal: %s\n", error.message); - dbus_error_free(&error); - dbus_message_unref(m); - return PA_HOOK_STOP; -@@ -320,7 +322,7 @@ static pa_hook_result_t rule_check_portal (pa_core *c, pa_access_data *d, struct - dbus_message_unref(m); - - if (!dbus_message_get_args(r, &error, DBUS_TYPE_OBJECT_PATH, &handle, DBUS_TYPE_INVALID)) { -- pa_log("Failed to parse AccessDevice result: %s\n", error.message); -+ pa_log_error("Failed to parse AccessDevice result: %s\n", error.message); - dbus_error_free(&error); - dbus_message_unref(r); - return PA_HOOK_STOP; -@@ -333,7 +335,7 @@ static pa_hook_result_t rule_check_portal (pa_core *c, pa_access_data *d, struct - &error); - dbus_connection_flush(pa_dbus_connection_get(u->connection)); - if (dbus_error_is_set(&error)) { -- pa_log("Failed to subscribe to Request signal: %s\n", error.message); -+ pa_log_error("Failed to subscribe to Request signal: %s\n", error.message); - dbus_error_free(&error); - return PA_HOOK_STOP; - } -@@ -407,7 +409,7 @@ static pa_hook_result_t filter_event (pa_core *c, pa_access_data *d, struct user - case PA_SUBSCRIPTION_EVENT_REMOVE: - /* if the client saw this object before, let the event go through */ - if (remove_event(cd, facility, d->object_index)) { -- pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ pa_log_debug("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); - return PA_HOOK_OK; - } - break; -@@ -415,7 +417,7 @@ static pa_hook_result_t filter_event (pa_core *c, pa_access_data *d, struct user - case PA_SUBSCRIPTION_EVENT_CHANGE: - /* if the client saw this object before, let it go through */ - if (find_event(cd, facility, d->object_index)) { -- pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ pa_log_debug("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); - return PA_HOOK_OK; - } - -@@ -428,7 +430,7 @@ static pa_hook_result_t filter_event (pa_core *c, pa_access_data *d, struct user - if (data.hook && pa_hook_fire(&c->access[data.hook], &data) == PA_HOOK_OK) { - /* client can inspect the object, remember for later */ - add_event(cd, facility, d->object_index); -- pa_log("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); -+ pa_log_debug("pass event %02x/%d to client %d", d->event, d->object_index, d->client_index); - return PA_HOOK_OK; - } - break; -@@ -438,7 +440,7 @@ static pa_hook_result_t filter_event (pa_core *c, pa_access_data *d, struct user - } - - block: -- pa_log("blocked event %02x/%d for client %d", d->event, d->object_index, d->client_index); -+ pa_log_debug("blocked event %02x/%d for client %d", d->event, d->object_index, d->client_index); - return PA_HOOK_STOP; - } - -@@ -455,10 +457,10 @@ client_is_sandboxed (pa_client *cl) - pid_t pid; - - if (cl->creds_valid) { -- pa_log ("client has trusted pid %d", cl->creds.pid); -+ pa_log_info ("client has trusted pid %d", cl->creds.pid); - } - else { -- pa_log ("no trusted pid found, assuming not sandboxed\n"); -+ pa_log_info ("no trusted pid found, assuming not sandboxed\n"); - return false; - } - -@@ -479,7 +481,7 @@ client_is_sandboxed (pa_client *cl) - if (strncmp(current, "1:name=systemd:", strlen("1:name=systemd:")) == 0) { - const char *p = strstr(current, "flatpak-"); - if (p && p - current < n) { -- pa_log("found a flatpak cgroup, assuming sandboxed\n"); -+ pa_log_info("found a flatpak cgroup, assuming sandboxed\n"); - result = true; - break; - } -@@ -490,18 +492,12 @@ client_is_sandboxed (pa_client *cl) - } - - static uint32_t find_policy_for_client (struct userdata *u, pa_client *cl) { -- char *s; -- -- s = pa_proplist_to_string(cl->proplist); -- pa_log ("client proplist %s", s); -- pa_xfree(s); -- - if (client_is_sandboxed (cl)) { -- pa_log("client is sandboxed, choosing portal policy\n"); -+ pa_log_info("client is sandboxed, choosing portal policy\n"); - return u->portal_policy; - } - else { -- pa_log("client not sandboxed, choosing default policy\n"); -+ pa_log_info("client not sandboxed, choosing default policy\n"); - return u->default_policy; - } - } -@@ -522,7 +518,7 @@ static pa_hook_result_t client_put_cb(pa_core *c, pa_object *o, struct userdata - - client_data_new(u, cl->index, policy, cl->creds.pid); - -- pa_log("client put: policy %d, pid %u\n", policy, cl->creds.pid); -+ pa_log_debug("client put: policy %d, pid %u\n", policy, cl->creds.pid); - - return PA_HOOK_OK; - } -@@ -546,7 +542,7 @@ static pa_hook_result_t client_auth_cb(pa_core *c, pa_object *o, struct userdata - cd->policy = policy; - cd->pid = cl->creds.pid; - -- pa_log("auth cb: policy %d, pid %u\n", cd->policy, cd->pid); -+ pa_log_debug("auth cb: policy %d, pid %u\n", cd->policy, cd->pid); - - return PA_HOOK_OK; - } -@@ -598,7 +594,7 @@ int pa__init(pa_module*m) { - pa_assert(m); - - if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { -- pa_log("Failed to parse module arguments"); -+ pa_log_error("Failed to parse module arguments"); - goto fail; - } - -@@ -609,7 +605,7 @@ int pa__init(pa_module*m) { - dbus_error_init(&error); - - if (!(u->connection = pa_dbus_bus_get (u->core, DBUS_BUS_SESSION, &error))) { -- pa_log("Failed to connect to session bus: %s\n", error.message); -+ pa_log_error("Failed to connect to session bus: %s\n", error.message); - dbus_error_free(&error); - } - -@@ -633,6 +629,9 @@ int pa__init(pa_module*m) { - u->hook[i] = pa_hook_connect(&u->core->access[i], PA_HOOK_EARLY - 1, cb, u); - } - -+ ap = access_policy_new(u, true); -+ u->permissive_policy = ap->index; -+ - ap = access_policy_new(u, false); - - ap->rule[PA_ACCESS_HOOK_VIEW_SINK] = rule_allow; -@@ -662,7 +661,7 @@ int pa__init(pa_module*m) { - ap->rule[PA_ACCESS_HOOK_SET_SOURCE_OUTPUT_VOLUME] = rule_check_owner; - ap->rule[PA_ACCESS_HOOK_KILL_SOURCE_OUTPUT] = rule_check_owner; - -- u->default_policy = ap->index; -+ u->restricted_policy = ap->index; - - ap = access_policy_new(u, false); - -@@ -695,6 +694,8 @@ int pa__init(pa_module*m) { - - u->portal_policy = ap->index; - -+ u->default_policy = u->permissive_policy; -+ - pa_modargs_free(ma); - return 0; - --- -2.9.3 - diff --git a/pulseaudio.spec b/pulseaudio.spec index 013457b..14dd871 100644 --- a/pulseaudio.spec +++ b/pulseaudio.spec @@ -1,5 +1,5 @@ -%global pa_major 10.0 -#global pa_minor 0 +%global pa_major 10.99 +%global pa_minor 1 #global snap 20141103 #global gitrel 327 @@ -25,7 +25,7 @@ Name: pulseaudio Summary: Improved Linux Sound Server Version: %{pa_major}%{?pa_minor:.%{pa_minor}} -Release: 4%{?snap:.%{snap}git%{shortcommit}}%{?dist} +Release: 1%{?snap:.%{snap}git%{shortcommit}}%{?dist} License: LGPLv2+ URL: http://www.freedesktop.org/wiki/Software/PulseAudio %if 0%{?gitrel} @@ -56,24 +56,6 @@ Patch3: pulseaudio-8.99.2-getaffinity.patch ## upstream patches ## upstreamable patches -Patch101: 0001-tagstruct-add-copy-method.patch -Patch102: 0002-tagstruct-don-t-forget-to-copy-the-length.patch -Patch103: 0003-subscribe-fix-typo.patch -Patch104: 0004-creds-add-pid-to-pa_creds-and-use-store-it-in-pa_cli.patch -Patch105: 0005-access-Add-access-control-hooks.patch -Patch106: 0006-module-access-add-example-access-module.patch -Patch107: 0007-module-access-add-async-handler-for-record.patch -Patch108: 0008-module-access-use-the-auth-hook-and-pid.patch -Patch109: 0009-pulsecore-Move-pa_core-structure-into-its-own-header.patch -Patch110: 0010-Don-t-access-pa_core-structures-directly.patch -Patch111: 0011-Add-access-checks.patch -Patch112: 0012-protocol-native-add-async-access-checks.patch -Patch113: 0013-core-add-current_client.patch -Patch114: 0014-core-ensure-maincontext-for-current-client.patch -Patch115: 0015-Add-flatpak-access-control.patch -Patch116: 0016-Make-flatpak-module-load.patch -Patch117: 0017-Make-sure-to-set-the-pid-in-auth_cb.patch -Patch118: 0018-Use-permissive-policy-by-default.patch BuildRequires: automake libtool BuildRequires: pkgconfig(bash-completion) @@ -261,25 +243,6 @@ This package contains GDM integration hooks for the PulseAudio sound server. %patch2 -p1 -b .disable_flat_volumes %patch3 -p1 -b .affinity -%patch101 -p1 -b .101 -%patch102 -p1 -b .102 -%patch103 -p1 -b .103 -%patch104 -p1 -b .104 -%patch105 -p1 -b .105 -%patch106 -p1 -b .106 -%patch107 -p1 -b .107 -%patch108 -p1 -b .108 -%patch109 -p1 -b .109 -%patch110 -p1 -b .110 -%patch111 -p1 -b .111 -%patch112 -p1 -b .112 -%patch113 -p1 -b .113 -%patch114 -p1 -b .114 -%patch115 -p1 -b .115 -%patch116 -p1 -b .116 -%patch117 -p1 -b .117 -%patch118 -p1 -b .118 - sed -i.no_consolekit -e \ 's/^load-module module-console-kit/#load-module module-console-kit/' \ src/daemon/default.pa.in @@ -622,6 +585,9 @@ exit 0 %changelog +* Tue Jul 25 2017 Rex Dieter - 10.99.1-1 +- pulseaudio-10.99.1 (#1474559) + * Mon Feb 13 2017 Wim Taymans - 10.0-4 - Add flatpak access control diff --git a/sources b/sources index d3eeb5d..4c3db15 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (pulseaudio-10.0.tar.xz) = 11d98b4b2000a41bdea92df253409452bc9b77d8bb309b6d14c439e3b902e3f90c69da00daff409e3859a54ad01c63a75be5723616bdcb492801d622a6406481 -SHA512 (pulseaudio-10.0.tar.xz.md5) = 6bacd8e56b8821eb839f3885535a0335f511a4ef4a9562c58a6d4c3db9ce474c1858bdadd099dc439c403f7697c795fccb9399fe87917291a251723796c8df6d -SHA512 (pulseaudio-10.0.tar.xz.sha1) = c8ddc213c9d932da435caeef056dedf43d66e09ec8ffd7afc545c3a47a5c95c5888c03282870f6195cbad2bc07e49bdb106669f3af80e3e64f1fec53962ba3e5 +SHA512 (pulseaudio-10.99.1.tar.xz) = 410758da3cf3431b5810b9a5790d60ed8fe0bba58f621f4ca8e7ba66be8dcdd53cbd8284105ee6694b04f81a37791c3e8c5fe4af3ee034e89dff0b66fdbde006 +SHA512 (pulseaudio-10.99.1.tar.xz.md5) = ef645038fd76874b6f5841ef3d7559cf09f4b1d12834ac7520e09112e6c629a4955da321fd73dd3097c438915e191cf047bb2b141e61a886e1c9e7ca1393166b +SHA512 (pulseaudio-10.99.1.tar.xz.sha1) = 9cfec7fd0a3ae13d2f1d61ae80485e48e4bf4d7d06169abc062063c289e155b2646fa0e14766e0d1145a58933b4310436e09959689ddf4a01d0739759282c52d