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");
{ .verb="verbose", .callback=verbose },
{ .verb="broadcast", .callback=broadcast },
{ .verb="hasperm", .callback=hasperm },
+ { .verb="appid", .callback=appid },
{ .verb="exit", .callback=exitnow },
{ .verb=NULL}
};
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'.
* 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
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);
};
/*
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);
+}
+
_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,
.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
};
/******************************************************************************
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
*****************************************************************************/
#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)
#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)
/* 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)
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);
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)
{ "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 },
"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,
.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
};
/*******************************************************************************/
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)
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 = {
.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 = {
.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
};
/******************************************************************************/