X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-api-dbus.c;h=13cbf7dbd0e891d4fdcd813d83f70a2be30d4a0f;hb=d69860c79a93845b78bbeafafbf04d12c60e63fa;hp=09af983fc4233d591165c710551581a0cb187fe8;hpb=074410d68f46148370b793eff8f34cf4724e3e31;p=src%2Fapp-framework-binder.git diff --git a/src/afb-api-dbus.c b/src/afb-api-dbus.c index 09af983f..13cbf7db 100644 --- a/src/afb-api-dbus.c +++ b/src/afb-api-dbus.c @@ -35,6 +35,7 @@ #include "afb-apis.h" #include "afb-api-so.h" #include "afb-context.h" +#include "afb-cred.h" #include "afb-evt.h" #include "afb-xreq.h" #include "verbose.h" @@ -43,7 +44,7 @@ static const char DEFAULT_PATH_PREFIX[] = "/org/agl/afb/api/"; struct dbus_memo; struct dbus_event; -struct destination; +struct origin; /* * The path given are of the form @@ -67,7 +68,7 @@ struct api_dbus struct { struct sd_bus_slot *slot_call; struct afb_evt_listener *listener; /* listener for broadcasted events */ - struct destination *destinations; + struct origin *origins; } server; }; }; @@ -311,7 +312,7 @@ static int api_dbus_client_on_reply(sd_bus_message *message, void *userdata, sd_ } /* on call, propagate it to the dbus service */ -static void api_dbus_client_xcall(void *closure, struct afb_xreq *xreq) +static void api_dbus_client_call(void *closure, struct afb_xreq *xreq) { struct api_dbus *api = closure; size_t size; @@ -576,6 +577,11 @@ static int api_dbus_client_on_manage_event(sd_bus_message *m, void *userdata, sd return 1; } +static struct afb_api_itf dbus_api_itf = { + .call = api_dbus_client_call, + .service_start = api_dbus_service_start +}; + /* adds a afb-dbus-service client api */ int afb_api_dbus_add_client(const char *path) { @@ -614,8 +620,7 @@ int afb_api_dbus_add_client(const char *path) /* record it as an API */ afb_api.closure = api; - afb_api.xcall = api_dbus_client_xcall; - afb_api.service_start = api_dbus_service_start; + afb_api.itf = &dbus_api_itf; if (afb_apis_add(api->api, afb_api) < 0) goto error2; @@ -646,12 +651,12 @@ static const struct afb_evt_itf evt_push_itf = { .remove = afb_api_dbus_server_event_remove }; -/******************* destination description part for server *****************************/ +/******************* origin description part for server *****************************/ -struct destination +struct origin { - /* link to next different destination */ - struct destination *next; + /* link to next different origin */ + struct origin *next; /* the server dbus-api */ struct api_dbus *api; @@ -659,55 +664,86 @@ struct destination /* count of references */ int refcount; - /* the destination */ + /* credentials of the origin */ + struct afb_cred *cred; + + /* the origin */ char name[1]; }; -static struct destination *afb_api_dbus_server_destination_get(struct api_dbus *api, const char *sender) +/* get the credentials for the message */ +static void init_origin_creds(struct origin *origin) { - struct destination *destination; + int rc; + sd_bus_creds *c; + uid_t uid; + gid_t gid; + pid_t pid; + const char *context; + + rc = sd_bus_get_name_creds(origin->api->sdbus, origin->name, + SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT, + &c); + if (rc < 0) + origin->cred = NULL; + else { + afb_cred_unref(origin->cred); + sd_bus_creds_get_uid(c, &uid); + sd_bus_creds_get_gid(c, &gid); + sd_bus_creds_get_pid(c, &pid); + sd_bus_creds_get_selinux_context(c, &context); + origin->cred = afb_cred_create(uid, gid, pid, context); + sd_bus_creds_unref(c); + } +} - /* searchs for an existing destination */ - destination = api->server.destinations; - while (destination != NULL) { - if (0 == strcmp(destination->name, sender)) { - destination->refcount++; - return destination; +static struct origin *afb_api_dbus_server_origin_get(struct api_dbus *api, const char *sender) +{ + struct origin *origin; + + /* searchs for an existing origin */ + origin = api->server.origins; + while (origin != NULL) { + if (0 == strcmp(origin->name, sender)) { + origin->refcount++; + return origin; } - destination = destination->next; + origin = origin->next; } /* not found, create it */ - destination = malloc(strlen(sender) + sizeof *destination); - if (destination == NULL) + origin = malloc(strlen(sender) + sizeof *origin); + if (origin == NULL) errno = ENOMEM; else { - destination->api = api; - destination->refcount = 1; - strcpy(destination->name, sender); - destination->next = api->server.destinations; - api->server.destinations = destination; + origin->api = api; + origin->refcount = 1; + strcpy(origin->name, sender); + init_origin_creds(origin); + origin->next = api->server.origins; + api->server.origins = origin; } - return destination; + return origin; } -static void afb_api_dbus_server_destination_unref(struct destination *destination) +static void afb_api_dbus_server_origin_unref(struct origin *origin) { - if (!--destination->refcount) { - struct destination **prv; + if (!--origin->refcount) { + struct origin **prv; - prv = &destination->api->server.destinations; - while(*prv != destination) + prv = &origin->api->server.origins; + while(*prv != origin) prv = &(*prv)->next; - *prv = destination->next; - free(destination); + *prv = origin->next; + afb_cred_unref(origin->cred); + free(origin); } } struct listener { - /* link to next different destination */ - struct destination *destination; + /* link to next different origin */ + struct origin *origin; /* the listener of events */ struct afb_evt_listener *listener; @@ -716,26 +752,26 @@ struct listener static void afb_api_dbus_server_listener_free(struct listener *listener) { afb_evt_listener_unref(listener->listener); - afb_api_dbus_server_destination_unref(listener->destination); + afb_api_dbus_server_origin_unref(listener->origin); free(listener); } -static struct listener *afb_api_dbus_server_listerner_get(struct api_dbus *api, const char *sender, struct afb_session *session) +static struct listener *afb_api_dbus_server_listener_get(struct api_dbus *api, const char *sender, struct afb_session *session) { int rc; struct listener *listener; - struct destination *destination; + struct origin *origin; - /* get the destination */ - destination = afb_api_dbus_server_destination_get(api, sender); - if (destination == NULL) + /* get the origin */ + origin = afb_api_dbus_server_origin_get(api, sender); + if (origin == NULL) return NULL; /* retrieves the stored listener */ - listener = afb_session_get_cookie(session, destination); + listener = afb_session_get_cookie(session, origin); if (listener != NULL) { /* found */ - afb_api_dbus_server_destination_unref(destination); + afb_api_dbus_server_origin_unref(origin); return listener; } @@ -744,17 +780,17 @@ static struct listener *afb_api_dbus_server_listerner_get(struct api_dbus *api, if (listener == NULL) errno = ENOMEM; else { - listener->destination = destination; - listener->listener = afb_evt_listener_create(&evt_push_itf, destination); + listener->origin = origin; + listener->listener = afb_evt_listener_create(&evt_push_itf, origin); if (listener->listener != NULL) { - rc = afb_session_set_cookie(session, destination, listener, (void*)afb_api_dbus_server_listener_free); + rc = afb_session_set_cookie(session, origin, listener, (void*)afb_api_dbus_server_listener_free); if (rc == 0) return listener; afb_evt_listener_unref(listener->listener); } free(listener); } - afb_api_dbus_server_destination_unref(destination); + afb_api_dbus_server_origin_unref(origin); return NULL; } @@ -772,9 +808,9 @@ struct dbus_req { }; /* decrement the reference count of the request and free/release it on falling to null */ -static void dbus_req_destroy(void *closure) +static void dbus_req_destroy(struct afb_xreq *xreq) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); afb_context_disconnect(&dreq->xreq.context); json_object_put(dreq->json); @@ -783,9 +819,9 @@ static void dbus_req_destroy(void *closure) } /* get the object of the request */ -static struct json_object *dbus_req_json(void *closure) +static struct json_object *dbus_req_json(struct afb_xreq *xreq) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); return dreq->json; } @@ -800,42 +836,42 @@ static void dbus_req_reply(struct dbus_req *dreq, uint8_t type, const char *firs ERROR("sending the reply failed"); } -static void dbus_req_success(void *closure, struct json_object *obj, const char *info) +static void dbus_req_success(struct afb_xreq *xreq, struct json_object *obj, const char *info) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); dbus_req_reply(dreq, RETOK, json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN), info); } -static void dbus_req_fail(void *closure, const char *status, const char *info) +static void dbus_req_fail(struct afb_xreq *xreq, const char *status, const char *info) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); dbus_req_reply(dreq, RETERR, status, info); } -static void afb_api_dbus_server_event_send(struct destination *destination, char order, const char *event, int eventid, const char *data, uint64_t msgid); +static void afb_api_dbus_server_event_send(struct origin *origin, char order, const char *event, int eventid, const char *data, uint64_t msgid); -static int dbus_req_subscribe(void *closure, struct afb_event event) +static int dbus_req_subscribe(struct afb_xreq *xreq, struct afb_event event) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); uint64_t msgid; int rc; rc = afb_evt_add_watch(dreq->listener->listener, event); sd_bus_message_get_cookie(dreq->message, &msgid); - afb_api_dbus_server_event_send(dreq->listener->destination, 'S', afb_evt_event_name(event), afb_evt_event_id(event), "", msgid); + afb_api_dbus_server_event_send(dreq->listener->origin, 'S', afb_evt_event_name(event), afb_evt_event_id(event), "", msgid); return rc; } -static int dbus_req_unsubscribe(void *closure, struct afb_event event) +static int dbus_req_unsubscribe(struct afb_xreq *xreq, struct afb_event event) { - struct dbus_req *dreq = closure; + struct dbus_req *dreq = CONTAINER_OF_XREQ(struct dbus_req, xreq); uint64_t msgid; int rc; sd_bus_message_get_cookie(dreq->message, &msgid); - afb_api_dbus_server_event_send(dreq->listener->destination, 'U', afb_evt_event_name(event), afb_evt_event_id(event), "", msgid); + afb_api_dbus_server_event_send(dreq->listener->origin, 'U', afb_evt_event_name(event), afb_evt_event_id(event), "", msgid); rc = afb_evt_remove_watch(dreq->listener->listener, event); return rc; } @@ -851,16 +887,16 @@ const struct afb_xreq_query_itf afb_api_dbus_xreq_itf = { /******************* server part **********************************/ -static void afb_api_dbus_server_event_send(struct destination *destination, char order, const char *event, int eventid, const char *data, uint64_t msgid) +static void afb_api_dbus_server_event_send(struct origin *origin, char order, const char *event, int eventid, const char *data, uint64_t msgid) { int rc; struct api_dbus *api; struct sd_bus_message *msg; - api = destination->api; + api = origin->api; msg = NULL; - rc = sd_bus_message_new_method_call(api->sdbus, &msg, destination->name, api->path, api->name, "event"); + rc = sd_bus_message_new_method_call(api->sdbus, &msg, origin->name, api->path, api->name, "event"); if (rc < 0) goto error; @@ -873,7 +909,7 @@ static void afb_api_dbus_server_event_send(struct destination *destination, char goto end; error: - ERROR("error while send event %c%s(%d) to %s", order, event, eventid, destination->name); + ERROR("error while send event %c%s(%d) to %s", order, event, eventid, origin->name); end: sd_bus_message_unref(msg); } @@ -940,12 +976,13 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd } /* connect to the context */ + afb_xreq_init(&dreq->xreq, &afb_api_dbus_xreq_itf); if (afb_context_connect(&dreq->xreq.context, uuid, NULL) < 0) goto out_of_memory; session = dreq->xreq.context.session; /* get the listener */ - listener = afb_api_dbus_server_listerner_get(api, sd_bus_message_get_sender(message), session); + listener = afb_api_dbus_server_listener_get(api, sd_bus_message_get_sender(message), session); if (listener == NULL) goto out_of_memory; @@ -958,12 +995,9 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd dreq->json = json_object_new_string(dreq->request); } dreq->listener = listener; - dreq->xreq.refcount = 1; - dreq->xreq.query = dreq; - dreq->xreq.queryitf = &afb_api_dbus_xreq_itf; dreq->xreq.api = api->api; dreq->xreq.verb = method; - afb_apis_xcall(&dreq->xreq); + afb_apis_call(&dreq->xreq); afb_xreq_unref(&dreq->xreq); return 1;