mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-16 07:00:00 -05:00
Implement access control
Move send and dispatch functions to the implementation. This makes it possible to place an access check before sending and dispatching. Add module-access that allows to bind and notify on globals owned by the client.
This commit is contained in:
parent
a8964ca657
commit
ee0aa6a2ac
27 changed files with 819 additions and 220 deletions
|
|
@ -37,6 +37,9 @@ typedef struct {
|
|||
SpaSource source;
|
||||
|
||||
bool disconnecting;
|
||||
|
||||
PinosSendFunc send_func;
|
||||
void *send_data;
|
||||
} PinosContextImpl;
|
||||
|
||||
/**
|
||||
|
|
@ -334,32 +337,40 @@ registry_dispatch_func (void *object,
|
|||
this->uri.node);
|
||||
if (proxy == NULL)
|
||||
goto no_mem;
|
||||
proxy->dispatch_func = node_dispatch_func;
|
||||
proxy->dispatch_data = impl;
|
||||
|
||||
pinos_proxy_set_dispatch (proxy,
|
||||
node_dispatch_func,
|
||||
impl);
|
||||
} else if (!strcmp (ng->type, PINOS_MODULE_URI)) {
|
||||
proxy = pinos_proxy_new (this,
|
||||
SPA_ID_INVALID,
|
||||
this->uri.module);
|
||||
if (proxy == NULL)
|
||||
goto no_mem;
|
||||
proxy->dispatch_func = module_dispatch_func;
|
||||
proxy->dispatch_data = impl;
|
||||
|
||||
pinos_proxy_set_dispatch (proxy,
|
||||
module_dispatch_func,
|
||||
impl);
|
||||
} else if (!strcmp (ng->type, PINOS_CLIENT_URI)) {
|
||||
proxy = pinos_proxy_new (this,
|
||||
SPA_ID_INVALID,
|
||||
this->uri.client);
|
||||
if (proxy == NULL)
|
||||
goto no_mem;
|
||||
proxy->dispatch_func = client_dispatch_func;
|
||||
proxy->dispatch_data = impl;
|
||||
|
||||
pinos_proxy_set_dispatch (proxy,
|
||||
client_dispatch_func,
|
||||
impl);
|
||||
} else if (!strcmp (ng->type, PINOS_LINK_URI)) {
|
||||
proxy = pinos_proxy_new (this,
|
||||
SPA_ID_INVALID,
|
||||
this->uri.link);
|
||||
if (proxy == NULL)
|
||||
goto no_mem;
|
||||
proxy->dispatch_func = link_dispatch_func;
|
||||
proxy->dispatch_data = impl;
|
||||
|
||||
pinos_proxy_set_dispatch (proxy,
|
||||
link_dispatch_func,
|
||||
impl);
|
||||
}
|
||||
if (proxy) {
|
||||
PinosMessageBind m;
|
||||
|
|
@ -431,12 +442,8 @@ on_context_data (SpaSource *source,
|
|||
pinos_log_error ("context %p: could not find proxy %u", this, id);
|
||||
continue;
|
||||
}
|
||||
if (proxy->dispatch_func == NULL) {
|
||||
pinos_log_error ("context %p: no dispatch function for proxy %u", this, id);
|
||||
continue;
|
||||
}
|
||||
|
||||
proxy->dispatch_func (proxy, type, p, proxy->dispatch_data);
|
||||
pinos_proxy_dispatch (proxy, type, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -502,8 +509,9 @@ pinos_context_new (PinosLoop *loop,
|
|||
|
||||
this->state = PINOS_CONTEXT_STATE_UNCONNECTED;
|
||||
|
||||
this->send_func = context_send_func;
|
||||
this->send_data = this;
|
||||
pinos_context_set_send (this,
|
||||
context_send_func,
|
||||
this);
|
||||
|
||||
pinos_map_init (&this->objects, 64);
|
||||
|
||||
|
|
@ -621,8 +629,9 @@ pinos_context_connect (PinosContext *context)
|
|||
if (context->core_proxy == NULL)
|
||||
goto no_proxy;
|
||||
|
||||
context->core_proxy->dispatch_func = core_dispatch_func;
|
||||
context->core_proxy->dispatch_data = impl;
|
||||
pinos_proxy_set_dispatch (context->core_proxy,
|
||||
core_dispatch_func,
|
||||
impl);
|
||||
|
||||
cu.props = &context->properties->dict;
|
||||
pinos_proxy_send_message (context->core_proxy,
|
||||
|
|
@ -636,8 +645,9 @@ pinos_context_connect (PinosContext *context)
|
|||
if (context->registry_proxy == NULL)
|
||||
goto no_registry;
|
||||
|
||||
context->registry_proxy->dispatch_func = registry_dispatch_func;
|
||||
context->registry_proxy->dispatch_data = impl;
|
||||
pinos_proxy_set_dispatch (context->registry_proxy,
|
||||
registry_dispatch_func,
|
||||
impl);
|
||||
|
||||
grm.seq = 0;
|
||||
grm.new_id = context->registry_proxy->id;
|
||||
|
|
@ -681,6 +691,35 @@ pinos_context_disconnect (PinosContext *context)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
pinos_context_set_send (PinosContext *context,
|
||||
PinosSendFunc func,
|
||||
void *data)
|
||||
{
|
||||
PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
|
||||
|
||||
impl->send_func = func;
|
||||
impl->send_data = data;
|
||||
}
|
||||
|
||||
|
||||
SpaResult
|
||||
pinos_context_send_message (PinosContext *context,
|
||||
PinosProxy *proxy,
|
||||
uint32_t opcode,
|
||||
void *message,
|
||||
bool flush)
|
||||
{
|
||||
PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
|
||||
|
||||
if (impl->send_func)
|
||||
return impl->send_func (proxy, proxy->id, opcode, message, flush, impl->send_data);
|
||||
|
||||
pinos_log_error ("context %p: send func not implemented", context);
|
||||
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void
|
||||
pinos_context_get_core_info (PinosContext *context,
|
||||
PinosCoreInfoCallback cb,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,12 @@ typedef struct _PinosContext PinosContext;
|
|||
#include <pinos/client/proxy.h>
|
||||
#include <pinos/client/uri.h>
|
||||
|
||||
typedef SpaResult (*PinosSendFunc) (void *object,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
void *message,
|
||||
bool flush,
|
||||
void *data);
|
||||
/**
|
||||
* PinosContextState:
|
||||
* @PINOS_CONTEXT_STATE_ERROR: context is in error
|
||||
|
|
@ -73,9 +79,6 @@ struct _PinosContext {
|
|||
SpaList stream_list;
|
||||
SpaList proxy_list;
|
||||
|
||||
PinosSendFunc send_func;
|
||||
void *send_data;
|
||||
|
||||
PinosContextState state;
|
||||
char *error;
|
||||
PINOS_SIGNAL (state_changed, (PinosListener *listener,
|
||||
|
|
@ -96,6 +99,16 @@ PinosContext * pinos_context_new (PinosLoop *loop,
|
|||
PinosProperties *properties);
|
||||
void pinos_context_destroy (PinosContext *context);
|
||||
|
||||
void pinos_context_set_send (PinosContext *context,
|
||||
PinosSendFunc func,
|
||||
void *data);
|
||||
|
||||
SpaResult pinos_context_send_message (PinosContext *context,
|
||||
PinosProxy *proxy,
|
||||
uint32_t opcode,
|
||||
void *message,
|
||||
bool flush);
|
||||
|
||||
bool pinos_context_connect (PinosContext *context);
|
||||
bool pinos_context_disconnect (PinosContext *context);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ struct _PinosMap {
|
|||
#define pinos_map_item_is_free(item) ((item)->next & 0x1)
|
||||
#define pinos_map_id_is_free(m,id) (pinos_map_item_is_free (pinos_map_get_item(m,id)))
|
||||
#define pinos_map_check_id(m,id) ((id) < pinos_map_get_size (m))
|
||||
#define pinos_map_has_item(m,id) (pinos_map_check_id(m,id) && !pinos_map_item_is_free(m, id))
|
||||
#define pinos_map_has_item(m,id) (pinos_map_check_id(m,id) && !pinos_map_id_is_free(m, id))
|
||||
#define pinos_map_lookup_unchecked(m,id) pinos_map_get_item(m,id)->data
|
||||
|
||||
static inline void
|
||||
|
|
@ -100,8 +100,11 @@ static inline void *
|
|||
pinos_map_lookup (PinosMap *map,
|
||||
uint32_t id)
|
||||
{
|
||||
if (SPA_LIKELY (pinos_map_check_id (map, id)))
|
||||
return pinos_map_lookup_unchecked (map, id);
|
||||
if (SPA_LIKELY (pinos_map_check_id (map, id))) {
|
||||
PinosMapItem *item = pinos_map_get_item (map, id);
|
||||
if (!pinos_map_item_is_free (item))
|
||||
return item->data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ extern "C" {
|
|||
|
||||
typedef struct _PinosProperties PinosProperties;
|
||||
|
||||
#include <spa/include/spa/dict.h>
|
||||
|
||||
struct _PinosProperties {
|
||||
SpaDict dict;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
|
||||
typedef struct {
|
||||
PinosProxy this;
|
||||
|
||||
PinosDispatchFunc dispatch_func;
|
||||
void *dispatch_data;
|
||||
} PinosProxyImpl;
|
||||
|
||||
PinosProxy *
|
||||
|
|
@ -40,8 +43,6 @@ pinos_proxy_new (PinosContext *context,
|
|||
|
||||
this->context = context;
|
||||
this->type = type;
|
||||
this->send_func = context->send_func;
|
||||
this->send_data = context->send_data;
|
||||
|
||||
pinos_signal_init (&this->destroy_signal);
|
||||
|
||||
|
|
@ -64,16 +65,41 @@ pinos_proxy_destroy (PinosProxy *proxy)
|
|||
free (impl);
|
||||
}
|
||||
|
||||
void
|
||||
pinos_proxy_set_dispatch (PinosProxy *proxy,
|
||||
PinosDispatchFunc func,
|
||||
void *data)
|
||||
{
|
||||
PinosProxyImpl *impl = SPA_CONTAINER_OF (proxy, PinosProxyImpl, this);
|
||||
|
||||
impl->dispatch_func = func;
|
||||
impl->dispatch_data = data;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
pinos_proxy_send_message (PinosProxy *proxy,
|
||||
uint32_t opcode,
|
||||
void *message,
|
||||
bool flush)
|
||||
{
|
||||
if (proxy->send_func)
|
||||
return proxy->send_func (proxy, proxy->id, opcode, message, flush, proxy->send_data);
|
||||
return pinos_context_send_message (proxy->context,
|
||||
proxy,
|
||||
opcode,
|
||||
message,
|
||||
flush);
|
||||
}
|
||||
|
||||
pinos_log_error ("proxy %p: send func not implemented", proxy);
|
||||
SpaResult
|
||||
pinos_proxy_dispatch (PinosProxy *proxy,
|
||||
uint32_t opcode,
|
||||
void *message)
|
||||
{
|
||||
PinosProxyImpl *impl = SPA_CONTAINER_OF (proxy, PinosProxyImpl, this);
|
||||
|
||||
if (impl->dispatch_func)
|
||||
return impl->dispatch_func (proxy, opcode, message, impl->dispatch_data);
|
||||
|
||||
pinos_log_error ("proxy %p: dispatch func not implemented", proxy);
|
||||
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,6 @@ extern "C" {
|
|||
|
||||
typedef struct _PinosProxy PinosProxy;
|
||||
|
||||
typedef SpaResult (*PinosSendFunc) (void *object,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
void *message,
|
||||
bool flush,
|
||||
void *data);
|
||||
|
||||
typedef SpaResult (*PinosDispatchFunc) (void *object,
|
||||
uint32_t opcode,
|
||||
|
|
@ -47,12 +41,7 @@ struct _PinosProxy {
|
|||
uint32_t id;
|
||||
uint32_t type;
|
||||
|
||||
PinosSendFunc send_func;
|
||||
void *send_data;
|
||||
PinosDispatchFunc dispatch_func;
|
||||
void *dispatch_data;
|
||||
|
||||
void *user_data;
|
||||
void *user_data;
|
||||
|
||||
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
|
||||
PinosProxy *proxy));
|
||||
|
|
@ -63,11 +52,18 @@ PinosProxy * pinos_proxy_new (PinosContext *contex
|
|||
uint32_t type);
|
||||
void pinos_proxy_destroy (PinosProxy *proxy);
|
||||
|
||||
void pinos_proxy_set_dispatch (PinosProxy *proxy,
|
||||
PinosDispatchFunc func,
|
||||
void *data);
|
||||
|
||||
SpaResult pinos_proxy_send_message (PinosProxy *proxy,
|
||||
uint32_t opcode,
|
||||
void *message,
|
||||
bool flush);
|
||||
|
||||
SpaResult pinos_proxy_dispatch (PinosProxy *proxy,
|
||||
uint32_t opcode,
|
||||
void *message);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -868,8 +868,9 @@ pinos_stream_connect (PinosStream *stream,
|
|||
SPA_ID_INVALID,
|
||||
0);
|
||||
|
||||
impl->node_proxy->dispatch_func = stream_dispatch_func;
|
||||
impl->node_proxy->dispatch_data = impl;
|
||||
pinos_proxy_set_dispatch (impl->node_proxy,
|
||||
stream_dispatch_func,
|
||||
impl);
|
||||
|
||||
ccn.seq = ++impl->seq;
|
||||
ccn.name = "client-node";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue