mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
protocol-native: add security context API
Add a new extension that can create a server on a user provided socket with user provided security properties. This is mainly used in flatpaks that want to create and bind a pipewire socket with specific permissions for the flatpak app. The flatpak will also provide an fd that will be closed when the server can be removed.
This commit is contained in:
parent
c5e8da7247
commit
e7846fc12a
8 changed files with 580 additions and 1 deletions
|
|
@ -175,6 +175,7 @@ static const struct spa_dict_item module_props[] = {
|
|||
|
||||
void pw_protocol_native_init(struct pw_protocol *protocol);
|
||||
void pw_protocol_native0_init(struct pw_protocol *protocol);
|
||||
int protocol_native_security_context_init(struct pw_impl_module *module, struct pw_protocol *protocol);
|
||||
|
||||
struct protocol_data {
|
||||
struct pw_impl_module *module;
|
||||
|
|
@ -233,6 +234,7 @@ struct server {
|
|||
struct pw_loop *loop;
|
||||
struct spa_source *source;
|
||||
struct spa_source *resume;
|
||||
struct spa_source *close;
|
||||
unsigned int activated:1;
|
||||
};
|
||||
|
||||
|
|
@ -809,6 +811,17 @@ socket_data(void *data, int fd, uint32_t mask)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
close_data(void *data, int fd, uint32_t mask)
|
||||
{
|
||||
struct server *s = data;
|
||||
|
||||
if (mask & (SPA_IO_HUP | SPA_IO_ERR)) {
|
||||
pw_log_info("server %p: closed socket %d %08x", s, fd, mask);
|
||||
pw_protocol_server_destroy(&s->this);
|
||||
}
|
||||
}
|
||||
|
||||
static int write_socket_address(struct server *s)
|
||||
{
|
||||
long v;
|
||||
|
|
@ -1337,6 +1350,8 @@ static void destroy_server(struct pw_protocol_server *server)
|
|||
pw_loop_destroy_source(s->loop, s->source);
|
||||
if (s->resume)
|
||||
pw_loop_destroy_source(s->loop, s->resume);
|
||||
if (s->close)
|
||||
pw_loop_destroy_source(s->loop, s->close);
|
||||
if (s->addr.sun_path[0] && !s->activated)
|
||||
unlink(s->addr.sun_path);
|
||||
if (s->lock_addr[0])
|
||||
|
|
@ -1464,10 +1479,58 @@ impl_add_server(struct pw_protocol *protocol,
|
|||
return add_server(protocol, core, props, NULL);
|
||||
}
|
||||
|
||||
static struct pw_protocol_server *
|
||||
impl_add_fd_server(struct pw_protocol *protocol,
|
||||
struct pw_impl_core *core,
|
||||
int listen_fd, int close_fd,
|
||||
const struct spa_dict *props)
|
||||
{
|
||||
struct pw_protocol_server *this;
|
||||
struct server *s;
|
||||
int res;
|
||||
|
||||
if ((s = create_server(protocol, core, props)) == NULL)
|
||||
return NULL;
|
||||
|
||||
this = &s->this;
|
||||
|
||||
pw_properties_setf(s->props, PW_KEY_SEC_SOCKET, "pipewire-fd-%d", listen_fd);
|
||||
|
||||
s->loop = pw_context_get_main_loop(protocol->context);
|
||||
if (s->loop == NULL) {
|
||||
res = -errno;
|
||||
goto error;
|
||||
}
|
||||
s->source = pw_loop_add_io(s->loop, listen_fd, SPA_IO_IN, true, socket_data, s);
|
||||
if (s->source == NULL) {
|
||||
res = -errno;
|
||||
goto error;
|
||||
}
|
||||
s->close = pw_loop_add_io(s->loop, close_fd, 0, true, close_data, s);
|
||||
if (s->close == NULL) {
|
||||
res = -errno;
|
||||
goto error;
|
||||
}
|
||||
if ((s->resume = pw_loop_add_event(s->loop, do_resume, s)) == NULL) {
|
||||
res = -errno;
|
||||
goto error;
|
||||
}
|
||||
|
||||
pw_log_info("%p: Listening on fd:%d", protocol, listen_fd);
|
||||
|
||||
return this;
|
||||
|
||||
error:
|
||||
destroy_server(this);
|
||||
errno = -res;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct pw_protocol_implementation protocol_impl = {
|
||||
PW_VERSION_PROTOCOL_IMPLEMENTATION,
|
||||
.new_client = impl_new_client,
|
||||
.add_server = impl_add_server,
|
||||
.add_fd_server = impl_add_fd_server,
|
||||
};
|
||||
|
||||
static struct spa_pod_builder *
|
||||
|
|
@ -1753,6 +1816,8 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args_str)
|
|||
goto error_cleanup;
|
||||
}
|
||||
|
||||
protocol_native_security_context_init(module, this);
|
||||
|
||||
props = pw_context_get_properties(context);
|
||||
pw_properties_update_keys(d->props, &props->dict, keys);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue