diff options
-rw-r--r-- | bindings/samples/HelloWorld.c | 8 | ||||
-rw-r--r-- | docs/afb-binding-references.md | 18 | ||||
-rw-r--r-- | include/afb/afb-req-common.h | 15 | ||||
-rw-r--r-- | src/afb-hook.c | 14 | ||||
-rw-r--r-- | src/afb-hook.h | 6 | ||||
-rw-r--r-- | src/afb-trace.c | 20 | ||||
-rw-r--r-- | src/afb-xreq.c | 19 |
7 files changed, 92 insertions, 8 deletions
diff --git a/bindings/samples/HelloWorld.c b/bindings/samples/HelloWorld.c index 4125e77f..c5a79deb 100644 --- a/bindings/samples/HelloWorld.c +++ b/bindings/samples/HelloWorld.c @@ -421,6 +421,13 @@ static void hasperm (afb_req request) afb_req_fail_f(request, "not-granted", "permission %s NOT granted", perm?:"(null)"); } +static void appid (afb_req request) +{ + char *aid = afb_req_get_application_id(request); + afb_req_success_f(request, aid ? json_object_new_string(aid) : NULL, "application is %s", aid?:"?"); + free(aid); +} + static int preinit() { AFB_NOTICE("hello binding comes to live"); @@ -460,6 +467,7 @@ static const afb_verb_v2 verbs[]= { { .verb="verbose", .callback=verbose }, { .verb="broadcast", .callback=broadcast }, { .verb="hasperm", .callback=hasperm }, + { .verb="appid", .callback=appid }, { .verb="exit", .callback=exitnow }, { .verb=NULL} }; diff --git a/docs/afb-binding-references.md b/docs/afb-binding-references.md index f5ab66d1..185f3ef4 100644 --- a/docs/afb-binding-references.md +++ b/docs/afb-binding-references.md @@ -694,11 +694,11 @@ Instead, you should use the macros: void afb_req_verbose(struct afb_req req, int level, const char *file, int line, const char * func, const char *fmt, ...); ``` -The function below allows a binding to check whether a client -has a permission of not. +The functions below allow a binding involved in the platform security +to explicitely check a permission of a client or to get the calling +application identity. ```C - /* * Check whether the 'permission' is granted or not to the client * identified by 'req'. @@ -706,6 +706,18 @@ has a permission of not. * Returns 1 if the permission is granted or 0 otherwise. */ int afb_req_has_permission(struct afb_req req, const char *permission); + +/* + * Get the application identifier of the client application for the + * request 'req'. + * + * Returns the application identifier or NULL when the application + * can not be identified. + * + * The returned value if not NULL must be freed by the caller + */ +inline char *afb_req_get_application_id(struct afb_req req); + ``` ## Logging macros diff --git a/include/afb/afb-req-common.h b/include/afb/afb-req-common.h index 8bb25f75..7d4473c5 100644 --- a/include/afb/afb-req-common.h +++ b/include/afb/afb-req-common.h @@ -76,6 +76,7 @@ struct afb_req_itf void (*subcall_req)(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*, struct afb_req), void *cb_closure); int (*has_permission)(void *closure, const char *permission); + char *(*get_application_id)(void *closure); }; /* @@ -445,3 +446,17 @@ static inline int afb_req_has_permission(struct afb_req req, const char *permiss return req.itf->has_permission(req.closure, permission); } +/* + * Get the application identifier of the client application for the + * request 'req'. + * + * Returns the application identifier or NULL when the application + * can not be identified. + * + * The returned value if not NULL must be freed by the caller + */ +static inline char *afb_req_get_application_id(struct afb_req req) +{ + return req.itf->get_application_id(req.closure); +} + diff --git a/src/afb-hook.c b/src/afb-hook.c index 92a4c829..188aabae 100644 --- a/src/afb-hook.c +++ b/src/afb-hook.c @@ -354,6 +354,11 @@ static void hook_xreq_has_permission_default_cb(void *closure, const struct afb_ _hook_xreq_(xreq, "has_permission(%s) -> %d", permission, result); } +static void hook_xreq_get_application_id_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, char *result) +{ + _hook_xreq_(xreq, "get_application_id() -> %s", result); +} + static struct afb_hook_xreq_itf hook_xreq_default_itf = { .hook_xreq_begin = hook_xreq_begin_default_cb, .hook_xreq_end = hook_xreq_end_default_cb, @@ -378,7 +383,8 @@ static struct afb_hook_xreq_itf hook_xreq_default_itf = { .hook_xreq_unstore = hook_xreq_unstore_default_cb, .hook_xreq_subcall_req = hook_xreq_subcall_req_default_cb, .hook_xreq_subcall_req_result = hook_xreq_subcall_req_result_default_cb, - .hook_xreq_has_permission = hook_xreq_has_permission_default_cb + .hook_xreq_has_permission = hook_xreq_has_permission_default_cb, + .hook_xreq_get_application_id = hook_xreq_get_application_id_default_cb }; /****************************************************************************** @@ -532,6 +538,12 @@ int afb_hook_xreq_has_permission(const struct afb_xreq *xreq, const char *permis return result; } +char *afb_hook_xreq_get_application_id(const struct afb_xreq *xreq, char *result) +{ + _HOOK_XREQ_(get_application_id, xreq, result); + return result; +} + /****************************************************************************** * section: hooking xreqs *****************************************************************************/ diff --git a/src/afb-hook.h b/src/afb-hook.h index a9c3894e..b3707a6d 100644 --- a/src/afb-hook.h +++ b/src/afb-hook.h @@ -75,6 +75,7 @@ struct afb_hookid #define afb_hook_flag_req_subcall_req 0x00200000 #define afb_hook_flag_req_subcall_req_result 0x00400000 #define afb_hook_flag_req_has_permission 0x00800000 +#define afb_hook_flag_req_get_application_id 0x01000000 /* common flags */ #define afb_hook_flags_req_life (afb_hook_flag_req_begin|afb_hook_flag_req_end) @@ -85,6 +86,7 @@ struct afb_hookid #define afb_hook_flags_req_subcalls (afb_hook_flag_req_subcall|afb_hook_flag_req_subcall_result\ |afb_hook_flag_req_subcall_req|afb_hook_flag_req_subcall_req_result\ |afb_hook_flag_req_subcallsync|afb_hook_flag_req_subcallsync_result) +#define afb_hook_flags_req_security (afb_hook_flag_req_has_permission|afb_hook_flag_req_get_application_id) /* extra flags */ #define afb_hook_flags_req_ref (afb_hook_flag_req_addref|afb_hook_flag_req_unref) @@ -94,7 +96,7 @@ struct afb_hookid /* predefined groups */ #define afb_hook_flags_req_common (afb_hook_flags_req_life|afb_hook_flags_req_args|afb_hook_flags_req_result\ |afb_hook_flags_req_session|afb_hook_flags_req_event|afb_hook_flags_req_subcalls\ - |afb_hook_flag_req_vverbose|afb_hook_flag_req_has_permission) + |afb_hook_flag_req_vverbose|afb_hook_flags_req_security) #define afb_hook_flags_req_extra (afb_hook_flags_req_common|afb_hook_flags_req_ref|afb_hook_flags_req_context\ |afb_hook_flags_req_stores) #define afb_hook_flags_req_all (afb_hook_flags_req_extra) @@ -124,6 +126,7 @@ struct afb_hook_xreq_itf { void (*hook_xreq_subcall_req)(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args); void (*hook_xreq_subcall_req_result)(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, int status, struct json_object *result); void (*hook_xreq_has_permission)(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, const char *permission, int result); + void (*hook_xreq_get_application_id)(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, char *result); }; extern void afb_hook_init_xreq(struct afb_xreq *xreq); @@ -157,6 +160,7 @@ extern void afb_hook_xreq_unstore(const struct afb_xreq *xreq); extern void afb_hook_xreq_subcall_req(const struct afb_xreq *xreq, const char *api, const char *verb, struct json_object *args); extern void afb_hook_xreq_subcall_req_result(const struct afb_xreq *xreq, int status, struct json_object *result); extern int afb_hook_xreq_has_permission(const struct afb_xreq *xreq, const char *permission, int result); +extern char *afb_hook_xreq_get_application_id(const struct afb_xreq *xreq, char *result); /********************************************************* * section hooking export (daemon interface) diff --git a/src/afb-trace.c b/src/afb-trace.c index c581611b..bf8db690 100644 --- a/src/afb-trace.c +++ b/src/afb-trace.c @@ -227,10 +227,13 @@ static struct flag xreq_flags[] = { /* must be sorted by names */ { "extra", afb_hook_flags_req_extra }, { "fail", afb_hook_flag_req_fail }, { "get", afb_hook_flag_req_get }, + { "get_application_id", afb_hook_flag_req_get_application_id }, + { "has_permission", afb_hook_flag_req_has_permission }, { "json", afb_hook_flag_req_json }, { "life", afb_hook_flags_req_life }, { "ref", afb_hook_flags_req_ref }, { "result", afb_hook_flags_req_result }, + { "security", afb_hook_flags_req_security }, { "session", afb_hook_flags_req_session }, { "session_close", afb_hook_flag_req_session_close }, { "session_set_LOA", afb_hook_flag_req_session_set_LOA }, @@ -456,6 +459,19 @@ static void hook_xreq_subcall_req_result(void *closure, const struct afb_hookid "result", result); } +static void hook_xreq_has_permission(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, const char *permission, int result) +{ + hook_xreq(closure, hookid, xreq, "has_permission", "{ss sb}", + "permission", permission, + "result", result); +} + +static void hook_xreq_get_application_id(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, char *result) +{ + hook_xreq(closure, hookid, xreq, "get_application_id", "{ss?}", + "result", result); +} + static struct afb_hook_xreq_itf hook_xreq_itf = { .hook_xreq_begin = hook_xreq_begin, .hook_xreq_end = hook_xreq_end, @@ -479,7 +495,9 @@ static struct afb_hook_xreq_itf hook_xreq_itf = { .hook_xreq_store = hook_xreq_store, .hook_xreq_unstore = hook_xreq_unstore, .hook_xreq_subcall_req = hook_xreq_subcall_req, - .hook_xreq_subcall_req_result = hook_xreq_subcall_req_result + .hook_xreq_subcall_req_result = hook_xreq_subcall_req_result, + .hook_xreq_has_permission = hook_xreq_has_permission, + .hook_xreq_get_application_id = hook_xreq_get_application_id }; /*******************************************************************************/ diff --git a/src/afb-xreq.c b/src/afb-xreq.c index 8a133519..de0710de 100644 --- a/src/afb-xreq.c +++ b/src/afb-xreq.c @@ -520,6 +520,12 @@ static int xreq_has_permission_cb(void*closure, const char *permission) return afb_auth_has_permission(xreq, permission); } +static char *xreq_get_application_id_cb(void*closure) +{ + struct afb_xreq *xreq = closure; + return xreq->cred && xreq->cred->id ? strdup(xreq->cred->id) : NULL; +} + /******************************************************************************/ static struct json_object *xreq_hooked_json_cb(void *closure) @@ -682,6 +688,13 @@ static int xreq_hooked_has_permission_cb(void*closure, const char *permission) return afb_hook_xreq_has_permission(xreq, permission, r); } +static char *xreq_hooked_get_application_id_cb(void*closure) +{ + struct afb_xreq *xreq = closure; + char *r = xreq_get_application_id_cb(closure); + return afb_hook_xreq_get_application_id(xreq, r); +} + /******************************************************************************/ const struct afb_req_itf xreq_itf = { @@ -704,7 +717,8 @@ const struct afb_req_itf xreq_itf = { .vverbose = xreq_vverbose_cb, .store = xreq_store_cb, .subcall_req = xreq_subcall_req_cb, - .has_permission = xreq_has_permission_cb + .has_permission = xreq_has_permission_cb, + .get_application_id = xreq_get_application_id_cb }; const struct afb_req_itf xreq_hooked_itf = { @@ -727,7 +741,8 @@ const struct afb_req_itf xreq_hooked_itf = { .vverbose = xreq_hooked_vverbose_cb, .store = xreq_hooked_store_cb, .subcall_req = xreq_hooked_subcall_req_cb, - .has_permission = xreq_hooked_has_permission_cb + .has_permission = xreq_hooked_has_permission_cb, + .get_application_id = xreq_hooked_get_application_id_cb }; /******************************************************************************/ |