mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-05 13:30:02 -05:00
core: add async create_client_node access check
This commit is contained in:
parent
4cf59e3953
commit
a5b39019d1
3 changed files with 191 additions and 37 deletions
|
|
@ -58,7 +58,7 @@ check_global_owner (PinosCore *core,
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpaResult
|
static SpaResult
|
||||||
do_check_global (PinosAccess *access,
|
do_view_global (PinosAccess *access,
|
||||||
PinosClient *client,
|
PinosClient *client,
|
||||||
PinosGlobal *global)
|
PinosGlobal *global)
|
||||||
{
|
{
|
||||||
|
|
@ -84,9 +84,65 @@ do_check_global (PinosAccess *access,
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SpaResult
|
||||||
|
do_create_node (PinosAccess *access,
|
||||||
|
PinosAccessData *data,
|
||||||
|
const char *factory_name,
|
||||||
|
const char *name,
|
||||||
|
PinosProperties *properties)
|
||||||
|
{
|
||||||
|
data->res = SPA_RESULT_OK;
|
||||||
|
data->complete_cb (data);
|
||||||
|
return SPA_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void
|
||||||
|
check_timeout (SpaSource *source,
|
||||||
|
void *d)
|
||||||
|
{
|
||||||
|
PinosAccessData *data = d;
|
||||||
|
|
||||||
|
data->res = SPA_RESULT_OK;
|
||||||
|
data->complete_cb (data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static SpaResult
|
||||||
|
do_create_client_node (PinosAccess *access,
|
||||||
|
PinosAccessData *data,
|
||||||
|
const char *name,
|
||||||
|
PinosProperties *properties)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
struct timespec value;
|
||||||
|
SpaSource *timer;
|
||||||
|
|
||||||
|
pinos_log_debug ("access %p: check %s %p", access, name, properties);
|
||||||
|
|
||||||
|
timer = pinos_loop_add_timer (data->resource->core->main_loop->loop,
|
||||||
|
check_timeout,
|
||||||
|
data->async_copy (data, 0));
|
||||||
|
value.tv_sec = 3;
|
||||||
|
value.tv_nsec = 0;
|
||||||
|
pinos_loop_update_timer (data->resource->core->main_loop->loop,
|
||||||
|
timer,
|
||||||
|
&value,
|
||||||
|
NULL,
|
||||||
|
false);
|
||||||
|
|
||||||
|
return SPA_RESULT_RETURN_ASYNC (0);
|
||||||
|
#else
|
||||||
|
data->res = SPA_RESULT_OK;
|
||||||
|
return SPA_RESULT_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static PinosAccess access_checks =
|
static PinosAccess access_checks =
|
||||||
{
|
{
|
||||||
do_check_global,
|
do_view_global,
|
||||||
|
do_create_node,
|
||||||
|
do_create_client_node,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ModuleImpl *
|
static ModuleImpl *
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,10 @@ typedef struct _PinosAccessData PinosAccessData;
|
||||||
|
|
||||||
struct _PinosAccessData {
|
struct _PinosAccessData {
|
||||||
SpaResult res;
|
SpaResult res;
|
||||||
|
PinosResource *resource;
|
||||||
|
void *(*async_copy) (PinosAccessData *data, size_t size);
|
||||||
void (*complete_cb) (PinosAccessData *data);
|
void (*complete_cb) (PinosAccessData *data);
|
||||||
void (*cancel_cb) (PinosAccessData *data);
|
void (*free_cb) (PinosAccessData *data);
|
||||||
void *user_data;
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -49,9 +51,18 @@ struct _PinosAccessData {
|
||||||
* Pinos Access support struct.
|
* Pinos Access support struct.
|
||||||
*/
|
*/
|
||||||
struct _PinosAccess {
|
struct _PinosAccess {
|
||||||
SpaResult (*check_global) (PinosAccess *access,
|
SpaResult (*view_global) (PinosAccess *access,
|
||||||
PinosClient *client,
|
PinosClient *client,
|
||||||
PinosGlobal *global);
|
PinosGlobal *global);
|
||||||
|
SpaResult (*create_node) (PinosAccess *access,
|
||||||
|
PinosAccessData *data,
|
||||||
|
const char *factory_name,
|
||||||
|
const char *name,
|
||||||
|
PinosProperties *properties);
|
||||||
|
SpaResult (*create_client_node) (PinosAccess *access,
|
||||||
|
PinosAccessData *data,
|
||||||
|
const char *name,
|
||||||
|
PinosProperties *properties);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ typedef struct {
|
||||||
|
|
||||||
} PinosCoreImpl;
|
} PinosCoreImpl;
|
||||||
|
|
||||||
#define ACCESS_CHECK_GLOBAL(client,global) (client->core->access && \
|
#define ACCESS_VIEW_GLOBAL(client,global) (client->core->access && \
|
||||||
client->core->access->check_global (client->core->access, \
|
client->core->access->view_global (client->core->access, \
|
||||||
client, global) == SPA_RESULT_OK)
|
client, global) == SPA_RESULT_OK)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -59,7 +59,7 @@ registry_bind (void *object,
|
||||||
if (&global->link == &core->global_list)
|
if (&global->link == &core->global_list)
|
||||||
goto no_id;
|
goto no_id;
|
||||||
|
|
||||||
if (!ACCESS_CHECK_GLOBAL (client, global))
|
if (!ACCESS_VIEW_GLOBAL (client, global))
|
||||||
goto no_id;
|
goto no_id;
|
||||||
|
|
||||||
pinos_log_debug ("global %p: bind object id %d to %d", global, id, new_id);
|
pinos_log_debug ("global %p: bind object id %d to %d", global, id, new_id);
|
||||||
|
|
@ -129,7 +129,7 @@ core_get_registry (void *object,
|
||||||
spa_list_insert (this->registry_resource_list.prev, ®istry_resource->link);
|
spa_list_insert (this->registry_resource_list.prev, ®istry_resource->link);
|
||||||
|
|
||||||
spa_list_for_each (global, &this->global_list, link) {
|
spa_list_for_each (global, &this->global_list, link) {
|
||||||
if (ACCESS_CHECK_GLOBAL (client, global))
|
if (ACCESS_VIEW_GLOBAL (client, global))
|
||||||
pinos_registry_notify_global (registry_resource,
|
pinos_registry_notify_global (registry_resource,
|
||||||
global->id,
|
global->id,
|
||||||
spa_type_map_get_type (this->type.map, global->type));
|
spa_type_map_get_type (this->type.map, global->type));
|
||||||
|
|
@ -161,32 +161,57 @@ core_create_node (void *object,
|
||||||
"not implemented");
|
"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
typedef struct {
|
||||||
core_create_client_node (void *object,
|
PinosAccessData data;
|
||||||
const char *name,
|
char *name;
|
||||||
const SpaDict *props,
|
PinosProperties *properties;
|
||||||
uint32_t new_id)
|
uint32_t new_id;
|
||||||
|
bool async;
|
||||||
|
} AccessCreateClientNode;
|
||||||
|
|
||||||
|
static void *
|
||||||
|
async_create_client_node_copy (PinosAccessData *data, size_t size)
|
||||||
{
|
{
|
||||||
PinosResource *resource = object;
|
AccessCreateClientNode *d;
|
||||||
|
|
||||||
|
d = calloc (1, sizeof (AccessCreateClientNode) + size);
|
||||||
|
memcpy (d, data, sizeof (AccessCreateClientNode));
|
||||||
|
d->name = strdup (d->name);
|
||||||
|
d->async = true;
|
||||||
|
d->data.user_data = SPA_MEMBER (d, sizeof (AccessCreateClientNode), void);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
async_create_client_node_free (PinosAccessData *data)
|
||||||
|
{
|
||||||
|
AccessCreateClientNode *d = (AccessCreateClientNode *) data;
|
||||||
|
|
||||||
|
if (d->async) {
|
||||||
|
if (d->data.free_cb)
|
||||||
|
d->data.free_cb (&d->data);
|
||||||
|
free (d->name);
|
||||||
|
free (d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
async_create_client_node_complete (PinosAccessData *data)
|
||||||
|
{
|
||||||
|
AccessCreateClientNode *d = (AccessCreateClientNode *) data;
|
||||||
|
PinosResource *resource = d->data.resource;
|
||||||
PinosClient *client = resource->client;
|
PinosClient *client = resource->client;
|
||||||
PinosClientNode *node;
|
PinosClientNode *node;
|
||||||
SpaResult res;
|
SpaResult res;
|
||||||
int data_fd, i;
|
int data_fd;
|
||||||
PinosProperties *properties;
|
|
||||||
|
|
||||||
properties = pinos_properties_new (NULL, NULL);
|
if (data->res != SPA_RESULT_OK)
|
||||||
if (properties == NULL)
|
goto denied;
|
||||||
goto no_mem;
|
|
||||||
|
|
||||||
for (i = 0; i < props->n_items; i++) {
|
|
||||||
pinos_properties_set (properties, props->items[i].key,
|
|
||||||
props->items[i].value);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = pinos_client_node_new (client,
|
node = pinos_client_node_new (client,
|
||||||
new_id,
|
d->new_id,
|
||||||
name,
|
d->name,
|
||||||
properties);
|
d->properties);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
goto no_mem;
|
goto no_mem;
|
||||||
|
|
||||||
|
|
@ -200,6 +225,68 @@ core_create_client_node (void *object,
|
||||||
|
|
||||||
pinos_client_node_notify_done (node->resource,
|
pinos_client_node_notify_done (node->resource,
|
||||||
data_fd);
|
data_fd);
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
no_mem:
|
||||||
|
pinos_log_error ("can't create client node");
|
||||||
|
pinos_core_notify_error (client->core_resource,
|
||||||
|
resource->id,
|
||||||
|
SPA_RESULT_NO_MEMORY,
|
||||||
|
"no memory");
|
||||||
|
goto done;
|
||||||
|
denied:
|
||||||
|
pinos_log_error ("create client node refused");
|
||||||
|
pinos_core_notify_error (client->core_resource,
|
||||||
|
resource->id,
|
||||||
|
SPA_RESULT_NO_PERMISSION,
|
||||||
|
"operation not allowed");
|
||||||
|
done:
|
||||||
|
async_create_client_node_free (&d->data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
core_create_client_node (void *object,
|
||||||
|
const char *name,
|
||||||
|
const SpaDict *props,
|
||||||
|
uint32_t new_id)
|
||||||
|
{
|
||||||
|
PinosResource *resource = object;
|
||||||
|
PinosClient *client = resource->client;
|
||||||
|
int i;
|
||||||
|
PinosProperties *properties;
|
||||||
|
AccessCreateClientNode access_data;
|
||||||
|
SpaResult res;
|
||||||
|
|
||||||
|
properties = pinos_properties_new (NULL, NULL);
|
||||||
|
if (properties == NULL)
|
||||||
|
goto no_mem;
|
||||||
|
|
||||||
|
for (i = 0; i < props->n_items; i++) {
|
||||||
|
pinos_properties_set (properties, props->items[i].key,
|
||||||
|
props->items[i].value);
|
||||||
|
}
|
||||||
|
|
||||||
|
access_data.data.resource = resource;
|
||||||
|
access_data.data.async_copy = async_create_client_node_copy;
|
||||||
|
access_data.data.complete_cb = async_create_client_node_complete;
|
||||||
|
access_data.data.free_cb = NULL;
|
||||||
|
access_data.name = (char *) name;
|
||||||
|
access_data.properties = properties;
|
||||||
|
access_data.new_id = new_id;
|
||||||
|
access_data.async = false;
|
||||||
|
|
||||||
|
if (client->core->access) {
|
||||||
|
access_data.data.res = SPA_RESULT_NO_PERMISSION;
|
||||||
|
res = client->core->access->create_client_node (client->core->access,
|
||||||
|
&access_data.data,
|
||||||
|
name,
|
||||||
|
properties);
|
||||||
|
} else {
|
||||||
|
res = access_data.data.res = SPA_RESULT_OK;
|
||||||
|
}
|
||||||
|
if (!SPA_RESULT_IS_ASYNC (res))
|
||||||
|
async_create_client_node_complete (&access_data.data);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
no_mem:
|
no_mem:
|
||||||
|
|
@ -406,7 +493,7 @@ pinos_core_add_global (PinosCore *core,
|
||||||
pinos_log_debug ("global %p: new %u %s, owner %p", this, this->id, type_name, owner);
|
pinos_log_debug ("global %p: new %u %s, owner %p", this, this->id, type_name, owner);
|
||||||
|
|
||||||
spa_list_for_each (registry, &core->registry_resource_list, link)
|
spa_list_for_each (registry, &core->registry_resource_list, link)
|
||||||
if (ACCESS_CHECK_GLOBAL (registry->client, this))
|
if (ACCESS_VIEW_GLOBAL (registry->client, this))
|
||||||
pinos_registry_notify_global (registry,
|
pinos_registry_notify_global (registry,
|
||||||
this->id,
|
this->id,
|
||||||
type_name);
|
type_name);
|
||||||
|
|
@ -445,7 +532,7 @@ pinos_global_destroy (PinosGlobal *global)
|
||||||
pinos_signal_emit (&global->destroy_signal, global);
|
pinos_signal_emit (&global->destroy_signal, global);
|
||||||
|
|
||||||
spa_list_for_each (registry, &core->registry_resource_list, link)
|
spa_list_for_each (registry, &core->registry_resource_list, link)
|
||||||
if (ACCESS_CHECK_GLOBAL (registry->client, global))
|
if (ACCESS_VIEW_GLOBAL (registry->client, global))
|
||||||
pinos_registry_notify_global_remove (registry, global->id);
|
pinos_registry_notify_global_remove (registry, global->id);
|
||||||
|
|
||||||
pinos_map_remove (&core->objects, global->id);
|
pinos_map_remove (&core->objects, global->id);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue