From fca2e14e1d57d7b89d1a6de07075cc0e6e157ca7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Mon, 23 May 2016 14:26:54 +0200 Subject: [PATCH] Setting and checking LOA MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I02c3795c6e212491605861228eb60b731be78537 Signed-off-by: José Bollo --- include/afb/afb-plugin.h | 28 ++++++++++++++++++++++++- include/afb/afb-req-itf.h | 12 +++++------ plugins/samples/ClientCtx.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ src/afb-api-so.c | 20 ++++++++++++++++-- src/afb-context.c | 11 ++++++---- src/afb-context.h | 2 +- 6 files changed, 109 insertions(+), 14 deletions(-) diff --git a/include/afb/afb-plugin.h b/include/afb/afb-plugin.h index c457f853..41e53ce1 100644 --- a/include/afb/afb-plugin.h +++ b/include/afb/afb-plugin.h @@ -59,7 +59,33 @@ enum AFB_session_v1 AFB_SESSION_CLOSE = 2, /* closes the session after authentification */ AFB_SESSION_RENEW = 4, /* refreshes the token after authentification */ AFB_SESSION_CHECK = 8, /* enforce authentification */ - AFB_SESSION_MASK = 15 /* convenient mask used internally, bit-or of the previous masks */ + + AFB_SESSION_LOA_GE = 16, /* check that the LOA is greater or equal to the given value */ + AFB_SESSION_LOA_LE = 32, /* check that the LOA is lesser or equal to the given value */ + AFB_SESSION_LOA_EQ = 48, /* check that the LOA is equal to the given value */ + + AFB_SESSION_LOA_SHIFT = 6, /* shift for LOA */ + AFB_SESSION_LOA_MASK = 3, /* mask for LOA */ + + AFB_SESSION_LOA_0 = 0, /* value for LOA of 0 */ + AFB_SESSION_LOA_1 = 64, /* value for LOA of 1 */ + AFB_SESSION_LOA_2 = 128, /* value for LOA of 2 */ + AFB_SESSION_LOA_3 = 192, /* value for LOA of 3 */ + + AFB_SESSION_LOA_LE_0 = AFB_SESSION_LOA_LE | AFB_SESSION_LOA_0, /* check LOA <= 0 */ + AFB_SESSION_LOA_LE_1 = AFB_SESSION_LOA_LE | AFB_SESSION_LOA_1, /* check LOA <= 1 */ + AFB_SESSION_LOA_LE_2 = AFB_SESSION_LOA_LE | AFB_SESSION_LOA_2, /* check LOA <= 2 */ + AFB_SESSION_LOA_LE_3 = AFB_SESSION_LOA_LE | AFB_SESSION_LOA_3, /* check LOA <= 3 */ + + AFB_SESSION_LOA_GE_0 = AFB_SESSION_LOA_GE | AFB_SESSION_LOA_0, /* check LOA >= 0 */ + AFB_SESSION_LOA_GE_1 = AFB_SESSION_LOA_GE | AFB_SESSION_LOA_1, /* check LOA >= 1 */ + AFB_SESSION_LOA_GE_2 = AFB_SESSION_LOA_GE | AFB_SESSION_LOA_2, /* check LOA >= 2 */ + AFB_SESSION_LOA_GE_3 = AFB_SESSION_LOA_GE | AFB_SESSION_LOA_3, /* check LOA >= 3 */ + + AFB_SESSION_LOA_EQ_0 = AFB_SESSION_LOA_EQ | AFB_SESSION_LOA_0, /* check LOA == 0 */ + AFB_SESSION_LOA_EQ_1 = AFB_SESSION_LOA_EQ | AFB_SESSION_LOA_1, /* check LOA == 1 */ + AFB_SESSION_LOA_EQ_2 = AFB_SESSION_LOA_EQ | AFB_SESSION_LOA_2, /* check LOA == 2 */ + AFB_SESSION_LOA_EQ_3 = AFB_SESSION_LOA_EQ | AFB_SESSION_LOA_3 /* check LOA == 3 */ }; /* diff --git a/include/afb/afb-req-itf.h b/include/afb/afb-req-itf.h index 6984d0fa..454c1817 100644 --- a/include/afb/afb-req-itf.h +++ b/include/afb/afb-req-itf.h @@ -42,7 +42,7 @@ struct afb_req_itf { void (*unref)(void *closure); void (*session_close)(void *closure); - void (*session_set_LOA)(void *closure, unsigned level); + int (*session_set_LOA)(void *closure, unsigned level); }; struct afb_req { @@ -97,7 +97,7 @@ static inline void *afb_req_context_get(struct afb_req req) static inline void afb_req_context_set(struct afb_req req, void *value, void (*free_value)(void*)) { - return req.itf->context_set(req.closure, value, free_value); + req.itf->context_set(req.closure, value, free_value); } static inline void *afb_req_context(struct afb_req req, void *(*create_value)(), void (*free_value)(void*)) @@ -118,20 +118,20 @@ static inline void afb_req_context_clear(struct afb_req req) static inline void afb_req_addref(struct afb_req req) { - return req.itf->addref(req.closure); + req.itf->addref(req.closure); } static inline void afb_req_unref(struct afb_req req) { - return req.itf->unref(req.closure); + req.itf->unref(req.closure); } static inline void afb_req_session_close(struct afb_req req) { - return req.itf->session_close(req.closure); + req.itf->session_close(req.closure); } -static inline void afb_req_session_set_LOA(struct afb_req req, unsigned level) +static inline int afb_req_session_set_LOA(struct afb_req req, unsigned level) { return req.itf->session_set_LOA(req.closure, level); } diff --git a/plugins/samples/ClientCtx.c b/plugins/samples/ClientCtx.c index 6b7eb631..353185c3 100644 --- a/plugins/samples/ClientCtx.c +++ b/plugins/samples/ClientCtx.c @@ -85,12 +85,62 @@ static void myClose (struct afb_req request) afb_req_success_f(request, NULL, "SUCCESS: plugin [%s] Close=[%d]\n", ctx->abcd, ctx->count); } +// Set the LOA +static void setLOA(struct afb_req request, unsigned loa) +{ + if (afb_req_session_set_LOA(request, loa)) + afb_req_success_f(request, NULL, "loa set to %u", loa); + else + afb_req_fail_f(request, "failed", "can't set loa to %u", loa); +} + +static void clientSetLOA0(struct afb_req request) +{ + setLOA(request, 0); +} + +static void clientSetLOA1(struct afb_req request) +{ + setLOA(request, 1); +} + +static void clientSetLOA2(struct afb_req request) +{ + setLOA(request, 2); +} + +static void clientSetLOA3(struct afb_req request) +{ + setLOA(request, 3); +} + +static void clientCheckLOA(struct afb_req request) +{ + afb_req_success(request, NULL, "LOA checked and okay"); +} + // NOTE: this sample does not use session to keep test a basic as possible // in real application most APIs should be protected with AFB_SESSION_CHECK static const struct AFB_verb_desc_v1 verbs[]= { {"create", AFB_SESSION_CREATE, myCreate , "Create a new session"}, {"action", AFB_SESSION_CHECK , myAction , "Use Session Context"}, {"close" , AFB_SESSION_CLOSE , myClose , "Free Context"}, + {"set_loa_0", AFB_SESSION_RENEW, clientSetLOA0 ,"Set level of authorisation to 0"}, + {"set_loa_1", AFB_SESSION_RENEW, clientSetLOA1 ,"Set level of authorisation to 1"}, + {"set_loa_2", AFB_SESSION_RENEW, clientSetLOA2 ,"Set level of authorisation to 2"}, + {"set_loa_3", AFB_SESSION_RENEW, clientSetLOA3 ,"Set level of authorisation to 3"}, + {"check_loa_ge_0", AFB_SESSION_LOA_GE_0, clientCheckLOA ,"Check whether level of authorisation is greater or equal to 0"}, + {"check_loa_ge_1", AFB_SESSION_LOA_GE_1, clientCheckLOA ,"Check whether level of authorisation is greater or equal to 1"}, + {"check_loa_ge_2", AFB_SESSION_LOA_GE_2, clientCheckLOA ,"Check whether level of authorisation is greater or equal to 2"}, + {"check_loa_ge_3", AFB_SESSION_LOA_GE_3, clientCheckLOA ,"Check whether level of authorisation is greater or equal to 3"}, + {"check_loa_le_0", AFB_SESSION_LOA_LE_0, clientCheckLOA ,"Check whether level of authorisation is lesser or equal to 0"}, + {"check_loa_le_1", AFB_SESSION_LOA_LE_1, clientCheckLOA ,"Check whether level of authorisation is lesser or equal to 1"}, + {"check_loa_le_2", AFB_SESSION_LOA_LE_2, clientCheckLOA ,"Check whether level of authorisation is lesser or equal to 2"}, + {"check_loa_le_3", AFB_SESSION_LOA_LE_3, clientCheckLOA ,"Check whether level of authorisation is lesser or equal to 3"}, + {"check_loa_eq_0", AFB_SESSION_LOA_EQ_0, clientCheckLOA ,"Check whether level of authorisation is equal to 0"}, + {"check_loa_eq_1", AFB_SESSION_LOA_EQ_1, clientCheckLOA ,"Check whether level of authorisation is equal to 1"}, + {"check_loa_eq_2", AFB_SESSION_LOA_EQ_2, clientCheckLOA ,"Check whether level of authorisation is equal to 2"}, + {"check_loa_eq_3", AFB_SESSION_LOA_EQ_3, clientCheckLOA ,"Check whether level of authorisation is equal to 3"}, {NULL} }; diff --git a/src/afb-api-so.c b/src/afb-api-so.c index 320834f7..9ab3e621 100644 --- a/src/afb-api-so.c +++ b/src/afb-api-so.c @@ -97,9 +97,9 @@ static void call_check(struct afb_req req, struct afb_context *context, const st { struct monitoring data; - int stag = (int)(verb->session & AFB_SESSION_MASK); + int stag = (int)verb->session; - if (stag != AFB_SESSION_NONE) { + if (stag != (AFB_SESSION_CREATE|AFB_SESSION_CLOSE|AFB_SESSION_RENEW|AFB_SESSION_CHECK|AFB_SESSION_LOA_EQ)) { if (!afb_context_check(context)) { afb_context_close(context); afb_req_fail(req, "failed", "invalid token's identity"); @@ -124,6 +124,22 @@ static void call_check(struct afb_req req, struct afb_context *context, const st afb_context_close(context); } + if ((stag & AFB_SESSION_LOA_GE) != 0) { + int loa = (stag >> AFB_SESSION_LOA_SHIFT) & AFB_SESSION_LOA_MASK; + if (!afb_context_check_loa(context, loa)) { + afb_req_fail(req, "failed", "invalid LOA"); + return; + } + } + + if ((stag & AFB_SESSION_LOA_LE) != 0) { + int loa = (stag >> AFB_SESSION_LOA_SHIFT) & AFB_SESSION_LOA_MASK; + if (afb_context_check_loa(context, loa + 1)) { + afb_req_fail(req, "failed", "invalid LOA"); + return; + } + } + data.req = req; data.action = verb->callback; afb_sig_monitor((void*)monitored_call, &data, api_timeout); diff --git a/src/afb-context.c b/src/afb-context.c index a7010dbb..0492ecbf 100644 --- a/src/afb-context.c +++ b/src/afb-context.c @@ -138,16 +138,19 @@ int afb_context_check_loa(struct afb_context *context, unsigned loa) return context->loa_in >= loa; } -void afb_context_change_loa(struct afb_context *context, unsigned loa) +int afb_context_change_loa(struct afb_context *context, unsigned loa) { - assert(context->validated); + if (!context->validated || loa > 7) + return 0; - if (loa == context->loa_in) + if (loa == context->loa_in && !context->loa_changed) context->loa_changing = 0; else { - context->loa_changing = 1; context->loa_out = loa & 7; + context->loa_changing = 1; + context->loa_changed = 0; } + return 1; } diff --git a/src/afb-context.h b/src/afb-context.h index 3f4301ec..27a262ac 100644 --- a/src/afb-context.h +++ b/src/afb-context.h @@ -54,5 +54,5 @@ extern void afb_context_close(struct afb_context *context); extern void afb_context_refresh(struct afb_context *context); extern int afb_context_check(struct afb_context *context); extern int afb_context_check_loa(struct afb_context *context, unsigned loa); -extern void afb_context_change_loa(struct afb_context *context, unsigned loa); +extern int afb_context_change_loa(struct afb_context *context, unsigned loa); -- 2.16.6