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:
Wim Taymans 2017-01-10 17:12:53 +01:00
parent a8964ca657
commit ee0aa6a2ac
27 changed files with 819 additions and 220 deletions

View file

@ -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,

View file

@ -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);

View file

@ -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;
}

View file

@ -26,6 +26,8 @@ extern "C" {
typedef struct _PinosProperties PinosProperties;
#include <spa/include/spa/dict.h>
struct _PinosProperties {
SpaDict dict;
};

View file

@ -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;
}

View file

@ -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

View file

@ -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";