aboutsummaryrefslogtreecommitdiffstats
path: root/src/afb-cred.c
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2018-04-09 18:16:07 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2018-06-15 17:57:36 +0200
commit4521c1e7ae5371ab9d639adc617d17fb4e8ded0c (patch)
treea8a1416a2d58c16ab3993c7e4dc405fc71daab6a /src/afb-cred.c
parent63682b4da9d3e892d1d0a671de860adc43068142 (diff)
api-v3: First draft
This commit introduces the bindings v3 API for bindings. The documentation has still to be improved and will come very soon. Change-Id: I8f9007370e29f671fdfd1da87fff7372a17db7af Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'src/afb-cred.c')
-rw-r--r--src/afb-cred.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/afb-cred.c b/src/afb-cred.c
index f09d4441..b7b3175e 100644
--- a/src/afb-cred.c
+++ b/src/afb-cred.c
@@ -18,6 +18,7 @@
#define _GNU_SOURCE
#include <stdlib.h>
+#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
@@ -26,6 +27,8 @@
#include <sys/socket.h>
#include "afb-cred.h"
+#include "verbose.h"
+
#define MAX_LABEL_LENGTH 1024
@@ -46,6 +49,10 @@
# define DEFAULT_PEERCRED_PID 0 /* no process */
#endif
+static char on_behalf_credential_permission[] = "urn:AGL:permission:*:partner:on-behalf-credentials";
+static char export_format[] = "%x:%x:%x-%s";
+static char import_format[] = "%x:%x:%x-%n";
+
static struct afb_cred *current;
static struct afb_cred *mkcred(uid_t uid, gid_t gid, pid_t pid, const char *label, size_t size)
@@ -70,6 +77,7 @@ static struct afb_cred *mkcred(uid_t uid, gid_t gid, pid_t pid, const char *labe
cred->uid = uid;
cred->gid = gid;
cred->pid = pid;
+ cred->exported = NULL;
dest = (char*)(&cred[1]);
cred->user = dest;
while(i)
@@ -175,3 +183,105 @@ struct afb_cred *afb_cred_current()
return afb_cred_addref(current);
}
+const char *afb_cred_export(struct afb_cred *cred)
+{
+ int rc;
+
+ if (!cred->exported) {
+ rc = asprintf((char**)&cred->exported,
+ export_format,
+ (int)cred->uid,
+ (int)cred->gid,
+ (int)cred->pid,
+ cred->label);
+ if (rc < 0) {
+ errno = ENOMEM;
+ cred->exported = NULL;
+ }
+ }
+ return cred->exported;
+}
+
+struct afb_cred *afb_cred_import(const char *string)
+{
+ struct afb_cred *cred;
+ int rc, uid, gid, pid, pos;
+
+ rc = sscanf(string, import_format, &uid, &gid, &pid, &pos);
+ if (rc == 3)
+ cred = afb_cred_create((uid_t)uid, (gid_t)gid, (pid_t)pid, &string[pos]);
+ else {
+ errno = EINVAL;
+ cred = NULL;
+ }
+ return cred;
+}
+
+struct afb_cred *afb_cred_mixed_on_behalf_import(struct afb_cred *cred, const char *context, const char *exported)
+
+{
+ struct afb_cred *imported;
+ if (exported) {
+ if (afb_cred_has_permission(cred, on_behalf_credential_permission, context)) {
+ imported = afb_cred_import(exported);
+ if (imported)
+ return imported;
+ ERROR("Can't import on behalf credentials: %m");
+ } else {
+ ERROR("On behalf credentials refused");
+ }
+ }
+ return afb_cred_addref(cred);
+}
+
+/*********************************************************************************/
+#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, const char *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, 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, const char *context)
+{
+ WARNING("Granting permission %s by default of backend", permission ?: "(null)");
+ return !!permission;
+}
+#endif
+