Setting and checking LOA
authorJosé Bollo <jose.bollo@iot.bzh>
Mon, 23 May 2016 12:26:54 +0000 (14:26 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Mon, 23 May 2016 12:27:09 +0000 (14:27 +0200)
Change-Id: I02c3795c6e212491605861228eb60b731be78537
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
include/afb/afb-plugin.h
include/afb/afb-req-itf.h
plugins/samples/ClientCtx.c
src/afb-api-so.c
src/afb-context.c
src/afb-context.h

index c457f85..41e53ce 100644 (file)
@@ -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 */
 };
 
 /*
index 6984d0f..454c181 100644 (file)
@@ -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);
 }
index 6b7eb63..353185c 100644 (file)
@@ -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}
 };
 
index 320834f..9ab3e62 100644 (file)
@@ -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);
index a7010db..0492ecb 100644 (file)
@@ -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;
 }
 
 
index 3f4301e..27a262a 100644 (file)
@@ -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);