summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/afb-context.c71
-rw-r--r--src/afb-context.h15
-rw-r--r--src/afb-cred.c60
-rw-r--r--src/afb-cred.h2
-rw-r--r--src/afb-perm.c93
-rw-r--r--src/afb-perm.h31
7 files changed, 206 insertions, 67 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d422f6b9..cf978c95 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -100,6 +100,7 @@ SET(AFB_LIB_SOURCES
afb-method.c
afb-monitor.c
afb-msg-json.c
+ afb-perm.c
afb-permission-text.c
afb-proto-ws.c
afb-session.c
diff --git a/src/afb-context.c b/src/afb-context.c
index 3d6dee06..7d2f3678 100644
--- a/src/afb-context.c
+++ b/src/afb-context.c
@@ -27,6 +27,7 @@
#include "afb-context.h"
#include "afb-token.h"
#include "afb-cred.h"
+#include "afb-perm.h"
#include "afb-permission-text.h"
#include "verbose.h"
@@ -160,7 +161,17 @@ void afb_context_on_behalf_other_context(struct afb_context *context, struct afb
int afb_context_has_permission(struct afb_context *context, const char *permission)
{
- return afb_cred_has_permission(context->credentials, permission, context);
+ return afb_perm_check(context, permission);
+}
+
+void afb_context_has_permission_async(
+ struct afb_context *context,
+ const char *permission,
+ void (*callback)(void *_closure, int _status),
+ void *closure
+)
+{
+ return afb_perm_check_async(context, permission, callback, closure);
}
const char *afb_context_uuid(struct afb_context *context)
@@ -191,9 +202,34 @@ void afb_context_close(struct afb_context *context)
context->closing = 1;
}
-int afb_context_check(struct afb_context *context)
+struct chkctx {
+ struct afb_context *context;
+ void (*callback)(void *_closure, int _status);
+ void *closure;
+};
+
+static void check_context_cb(void *closure_chkctx, int status)
{
+ struct chkctx *cc = closure_chkctx;
+ struct afb_context *context = cc->context;
+ void (*callback)(void*,int) = cc->callback;
+ void *closure = cc->closure;
+
+ free(cc);
+ if (status)
+ context->validated = 1;
+ else
+ context->invalidated = 1;
+ callback(closure, status);
+}
+
+static int check_context(
+ struct afb_context *context,
+ void (*callback)(void *_closure, int _status),
+ void *closure
+) {
int r;
+ struct chkctx *cc;
if (context->validated)
r = 1;
@@ -201,9 +237,21 @@ int afb_context_check(struct afb_context *context)
r = 0;
else {
if (context->super)
- r = afb_context_check(context->super);
- else
+ r = check_context(context->super, callback, closure);
+ else if (!callback)
r = afb_context_has_permission(context, afb_permission_token_valid);
+ else {
+ cc = malloc(sizeof *cc);
+ if (cc) {
+ cc->context = context;
+ cc->callback = callback;
+ cc->closure = closure;
+ afb_context_has_permission_async(context, afb_permission_token_valid, check_context_cb, cc);
+ return -1;
+ }
+ ERROR("out-of-memory");
+ r = 0;
+ }
if (r)
context->validated = 1;
else
@@ -212,6 +260,21 @@ int afb_context_check(struct afb_context *context)
return r;
}
+int afb_context_check(struct afb_context *context)
+{
+ return check_context(context, 0, 0);
+}
+
+void afb_context_check_async(
+ struct afb_context *context,
+ void (*callback)(void *_closure, int _status),
+ void *closure
+) {
+ int r = check_context(context, callback, closure);
+ if (r >= 0)
+ callback(closure, r);
+}
+
static inline const void *loa_key(struct afb_context *context)
{
return (const void*)(1+(intptr_t)(context->api_key));
diff --git a/src/afb-context.h b/src/afb-context.h
index e3cf4151..c5d50914 100644
--- a/src/afb-context.h
+++ b/src/afb-context.h
@@ -59,10 +59,23 @@ extern void afb_context_change_cred(struct afb_context *context, struct afb_cred
extern int afb_context_on_behalf_import(struct afb_context *context, const char *exported);
extern const char *afb_context_on_behalf_export(struct afb_context *context);
extern void afb_context_on_behalf_other_context(struct afb_context *context, struct afb_context *other);
+
extern int afb_context_has_permission(struct afb_context *context, const char *permission);
+extern void afb_context_has_permission_async(
+ struct afb_context *context,
+ const char *permission,
+ void (*callback)(void *_closure, int _status),
+ void *closure
+);
-extern void afb_context_close(struct afb_context *context);
extern int afb_context_check(struct afb_context *context);
+extern void afb_context_check_async(
+ struct afb_context *context,
+ void (*callback)(void *_closure, int _status),
+ void *closure
+);
+
+extern void afb_context_close(struct afb_context *context);
extern int afb_context_check_loa(struct afb_context *context, unsigned loa);
extern int afb_context_change_loa(struct afb_context *context, unsigned loa);
extern unsigned afb_context_get_loa(struct afb_context *context);
diff --git a/src/afb-cred.c b/src/afb-cred.c
index b6e6feba..88c29c5e 100644
--- a/src/afb-cred.c
+++ b/src/afb-cred.c
@@ -28,8 +28,6 @@
#include <sys/socket.h>
#include "afb-cred.h"
-#include "afb-context.h"
-#include "afb-token.h"
#include "verbose.h"
#define MAX_LABEL_LENGTH 1024
@@ -219,61 +217,3 @@ struct afb_cred *afb_cred_import(const char *string)
}
return cred;
}
-
-/*********************************************************************************/
-static const char *token_of_context(struct afb_context *context)
-{
- return context && context->token ? afb_token_string(context->token) : "X";
-}
-
-/*********************************************************************************/
-#ifdef BACKEND_PERMISSION_IS_CYNARA
-
-#include <pthread.h>
-#include <cynara-client.h>
-
-static cynara *handle;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-int afb_cred_has_permission(struct afb_cred *cred, const char *permission, struct afb_context *context)
-{
- int rc;
-
- if (!cred) {
- /* case of permission for self */
- return 1;
- }
- if (!permission) {
- ERROR("Got a null permission!");
- return 0;
- }
-
- /* cynara isn't reentrant */
- pthread_mutex_lock(&mutex);
-
- /* lazy initialisation */
- if (!handle) {
- rc = cynara_initialize(&handle, NULL);
- if (rc != CYNARA_API_SUCCESS) {
- handle = NULL;
- ERROR("cynara initialisation failed with code %d", rc);
- return 0;
- }
- }
-
- /* query cynara permission */
- rc = cynara_check(handle, cred->label, token_of_context(context), cred->user, permission);
-
- pthread_mutex_unlock(&mutex);
- return rc == CYNARA_API_ACCESS_ALLOWED;
-}
-
-/*********************************************************************************/
-#else
-int afb_cred_has_permission(struct afb_cred *cred, const char *permission, struct afb_context *context)
-{
- WARNING("Granting permission %s by default of backend", permission ?: "(null)");
- return !!permission;
-}
-#endif
-
diff --git a/src/afb-cred.h b/src/afb-cred.h
index 46639408..9483ac33 100644
--- a/src/afb-cred.h
+++ b/src/afb-cred.h
@@ -39,7 +39,5 @@ extern struct afb_cred *afb_cred_create_for_socket(int fd);
extern struct afb_cred *afb_cred_addref(struct afb_cred *cred);
extern void afb_cred_unref(struct afb_cred *cred);
-extern int afb_cred_has_permission(struct afb_cred *cred, const char *permission, struct afb_context *context);
-
extern const char *afb_cred_export(struct afb_cred *cred);
extern struct afb_cred *afb_cred_import(const char *string);
diff --git a/src/afb-perm.c b/src/afb-perm.c
new file mode 100644
index 00000000..e3fab4b6
--- /dev/null
+++ b/src/afb-perm.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017-2019 "IoT.bzh"
+ * Author: José Bollo <jose.bollo@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#include "afb-context.h"
+#include "afb-cred.h"
+#include "afb-token.h"
+#include "afb-session.h"
+#include "verbose.h"
+
+/*********************************************************************************/
+
+static inline const char *session_of_context(struct afb_context *context)
+{
+ return context->token ? afb_token_string(context->token)
+ : context->session ? afb_session_uuid(context->session)
+ : "";
+}
+
+/*********************************************************************************/
+#ifdef BACKEND_PERMISSION_IS_CYNARA
+
+#include <pthread.h>
+#include <cynara-client.h>
+
+static cynara *handle;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int afb_perm_check(struct afb_context *context, const char *permission)
+{
+ int rc;
+
+ if (!context->credentials) {
+ /* case of permission for self */
+ return 1;
+ }
+ if (!permission) {
+ ERROR("Got a null permission!");
+ return 0;
+ }
+
+ /* cynara isn't reentrant */
+ pthread_mutex_lock(&mutex);
+
+ /* lazy initialisation */
+ if (!handle) {
+ rc = cynara_initialize(&handle, NULL);
+ if (rc != CYNARA_API_SUCCESS) {
+ handle = NULL;
+ ERROR("cynara initialisation failed with code %d", rc);
+ return 0;
+ }
+ }
+
+ /* query cynara permission */
+ rc = cynara_check(handle, context->credentials->label, session_of_context(context), context->credentials->user, permission);
+
+ pthread_mutex_unlock(&mutex);
+ return rc == CYNARA_API_ACCESS_ALLOWED;
+}
+/*********************************************************************************/
+#else
+int afb_perm_check(struct afb_context *context, const char *permission)
+{
+ NOTICE("Granting permission %s by default of backend", permission ?: "(null)");
+ return !!permission;
+}
+#endif
+
+void afb_perm_check_async(
+ struct afb_context *context,
+ const char *permission,
+ void (*callback)(void *closure, int status),
+ void *closure
+)
+{
+ callback(closure, afb_perm_check(context, permission));
+}
diff --git a/src/afb-perm.h b/src/afb-perm.h
new file mode 100644
index 00000000..4a4df84b
--- /dev/null
+++ b/src/afb-perm.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017-2019 "IoT.bzh"
+ * Author: José Bollo <jose.bollo@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <sys/types.h>
+
+struct afb_context;
+
+extern int afb_perm_check(struct afb_context *context, const char *permission);
+
+extern void afb_perm_check_async(
+ struct afb_context *context,
+ const char *permission,
+ void (*callback)(void *closure, int status),
+ void *closure
+);