diff options
author | José Bollo <jose.bollo@iot.bzh> | 2018-04-09 18:16:07 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2018-06-15 17:57:36 +0200 |
commit | 4521c1e7ae5371ab9d639adc617d17fb4e8ded0c (patch) | |
tree | a8a1416a2d58c16ab3993c7e4dc405fc71daab6a /src/afb-cred.c | |
parent | 63682b4da9d3e892d1d0a671de860adc43068142 (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.c | 110 |
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 + |