From b70caad7da2eaea85db06dec8377b1cbebcec997 Mon Sep 17 00:00:00 2001 From: José Bollo Date: Fri, 29 Nov 2019 11:12:31 +0100 Subject: afb-context: Move credentials to context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The split between context and credentials in requests was somehow artificial and awkward. This change move the credentials to the context and removes as many references to credentials as possible in favor of working on contexts. Change the value returned by afb_auth_check to be 1 if validated, 0 or less than zero if not validated. Bug-AGL: SPEC-2968 Signed-off-by: José Bollo Change-Id: I979dc841e03247e126e3fa8433a1cc0d4108adf0 --- src/CMakeLists.txt | 1 + src/afb-api-dbus.c | 10 +++-- src/afb-auth.c | 29 ++++++------- src/afb-auth.h | 9 ++-- src/afb-calls.c | 19 ++++---- src/afb-context.c | 108 +++++++++++++++++++++++++++++++++++++--------- src/afb-context.h | 23 +++++++--- src/afb-cred.c | 19 -------- src/afb-cred.h | 3 -- src/afb-export.c | 3 +- src/afb-hook.c | 16 ++++--- src/afb-hreq.c | 4 +- src/afb-permission-text.c | 20 +++++++++ src/afb-permission-text.h | 20 +++++++++ src/afb-stub-ws.c | 5 +-- src/afb-supervision.c | 4 +- src/afb-trace.c | 22 +++++----- src/afb-ws-json1.c | 6 +-- src/afb-xreq.c | 29 +++++++------ src/afb-xreq.h | 1 - src/main-afb-daemon.c | 2 +- 21 files changed, 222 insertions(+), 131 deletions(-) create mode 100644 src/afb-permission-text.c create mode 100644 src/afb-permission-text.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d290327c..d422f6b9 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-permission-text.c afb-proto-ws.c afb-session.c afb-socket.c diff --git a/src/afb-api-dbus.c b/src/afb-api-dbus.c index 0ac4f499..04943c6e 100644 --- a/src/afb-api-dbus.c +++ b/src/afb-api-dbus.c @@ -682,6 +682,7 @@ static void init_origin_creds(struct origin *origin) gid_t gid; pid_t pid; const char *context; + struct afb_cred *ocred; rc = sd_bus_get_name_creds(origin->api->sdbus, origin->name, SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT, @@ -689,13 +690,14 @@ static void init_origin_creds(struct origin *origin) if (rc < 0) origin->cred = NULL; else { - afb_cred_unref(origin->cred); sd_bus_creds_get_uid(c, &uid); sd_bus_creds_get_gid(c, &gid); sd_bus_creds_get_pid(c, &pid); sd_bus_creds_get_selinux_context(c, &context); + ocred = origin->cred; origin->cred = afb_cred_create(uid, gid, pid, context); sd_bus_creds_unref(c); + afb_cred_unref(ocred); } } @@ -970,7 +972,7 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd /* connect to the context */ afb_xreq_init(&dreq->xreq, &afb_api_dbus_xreq_itf); - if (afb_context_connect(&dreq->xreq.context, uuid, NULL) < 0) + if (afb_context_connect(&dreq->xreq.context, uuid, NULL, NULL) < 0) goto out_of_memory; session = dreq->xreq.context.session; @@ -980,8 +982,8 @@ static int api_dbus_server_on_object_called(sd_bus_message *message, void *userd goto out_of_memory; /* fulfill the request and emit it */ - dreq->xreq.context.flags = flags; - dreq->xreq.cred = afb_cred_mixed_on_behalf_import(listener->origin->cred, &dreq->xreq.context, creds && creds[0] ? creds : NULL); + afb_context_change_cred(&dreq->xreq.context, listener->origin->cred); + afb_context_on_behalf_import(&dreq->xreq.context, creds); dreq->message = sd_bus_message_ref(message); dreq->json = json_tokener_parse_verbose(dreq->request, &jerr); if (jerr != json_tokener_success) { diff --git a/src/afb-auth.c b/src/afb-auth.c index 01412128..3606b3cb 100644 --- a/src/afb-auth.c +++ b/src/afb-auth.c @@ -30,10 +30,9 @@ #include "afb-auth.h" #include "afb-context.h" #include "afb-xreq.h" -#include "afb-cred.h" #include "verbose.h" -int afb_auth_check(struct afb_xreq *xreq, const struct afb_auth *auth) +int afb_auth_check(struct afb_context *context, const struct afb_auth *auth) { switch (auth->type) { default: @@ -41,39 +40,35 @@ int afb_auth_check(struct afb_xreq *xreq, const struct afb_auth *auth) return 0; case afb_auth_Token: - return afb_context_check(&xreq->context); + return afb_context_check(context); case afb_auth_LOA: - return afb_context_check_loa(&xreq->context, auth->loa); + return afb_context_check_loa(context, auth->loa); case afb_auth_Permission: - return afb_auth_has_permission(xreq, auth->text); + return afb_context_has_permission(context, auth->text); case afb_auth_Or: - return afb_auth_check(xreq, auth->first) || afb_auth_check(xreq, auth->next); + return afb_auth_check(context, auth->first) || afb_auth_check(context, auth->next); case afb_auth_And: - return afb_auth_check(xreq, auth->first) && afb_auth_check(xreq, auth->next); + return afb_auth_check(context, auth->first) && afb_auth_check(context, auth->next); case afb_auth_Not: - return !afb_auth_check(xreq, auth->first); + return !afb_auth_check(context, auth->first); case afb_auth_Yes: return 1; } } -int afb_auth_has_permission(struct afb_xreq *xreq, const char *permission) -{ - return afb_cred_has_permission(xreq->cred, permission, &xreq->context); -} #if WITH_LEGACY_BINDING_V1 int afb_auth_check_and_set_session_x1(struct afb_xreq *xreq, int sessionflags) { int loa; - if ((sessionflags & (AFB_SESSION_CLOSE_X1|AFB_SESSION_RENEW_X1|AFB_SESSION_CHECK_X1|AFB_SESSION_LOA_EQ_X1)) != 0) { + if ((sessionflags & (AFB_SESSION_CLOSE_X1|AFB_SESSION_CHECK_X1|AFB_SESSION_LOA_EQ_X1)) != 0) { if (!afb_context_check(&xreq->context)) { afb_context_close(&xreq->context); return afb_xreq_reply_invalid_token(xreq); @@ -97,11 +92,11 @@ int afb_auth_check_and_set_session_x1(struct afb_xreq *xreq, int sessionflags) afb_context_close(&xreq->context); } - return 0; + return 1; } #endif -int afb_auth_check_and_set_session_x2(struct afb_xreq *xreq, uint32_t sessionflags, const struct afb_auth *auth) +int afb_auth_check_and_set_session_x2(struct afb_xreq *xreq, const struct afb_auth *auth, uint32_t sessionflags) { int loa; @@ -116,13 +111,13 @@ int afb_auth_check_and_set_session_x2(struct afb_xreq *xreq, uint32_t sessionfla if (loa && !afb_context_check_loa(&xreq->context, loa)) return afb_xreq_reply_insufficient_scope(xreq, "invalid LOA"); - if (auth && !afb_auth_check(xreq, auth)) + if (auth && !afb_auth_check(&xreq->context, auth)) return afb_xreq_reply_insufficient_scope(xreq, NULL /* TODO */); if ((sessionflags & AFB_SESSION_CLOSE_X2) != 0) afb_context_close(&xreq->context); - return 0; + return 1; } /*********************************************************************************/ diff --git a/src/afb-auth.h b/src/afb-auth.h index bf4a8466..3ace3c0a 100644 --- a/src/afb-auth.h +++ b/src/afb-auth.h @@ -18,16 +18,17 @@ #pragma once struct afb_auth; +struct afb_context; struct afb_xreq; struct json_object; -extern int afb_auth_check(struct afb_xreq *xreq, const struct afb_auth *auth); -extern int afb_auth_has_permission(struct afb_xreq *xreq, const char *permission); +extern int afb_auth_check(struct afb_context *context, const struct afb_auth *auth); -extern int afb_auth_check_and_set_session_x2(struct afb_xreq *xreq, uint32_t session, const struct afb_auth *auth); +extern int afb_auth_check_and_set_session_x2(struct afb_xreq *xreq, const struct afb_auth *auth, uint32_t session); extern struct json_object *afb_auth_json_x2(const struct afb_auth *auth, uint32_t session); #if WITH_LEGACY_BINDING_V1 extern int afb_auth_check_and_set_session_x1(struct afb_xreq *xreq, int session); extern struct json_object *afb_auth_json_x1(int session); -#endif \ No newline at end of file +#endif + diff --git a/src/afb-calls.c b/src/afb-calls.c index 958b9a87..6254f33a 100644 --- a/src/afb-calls.c +++ b/src/afb-calls.c @@ -27,7 +27,6 @@ #include #include "afb-calls.h" -#include "afb-cred.h" #include "afb-evt.h" #include "afb-export.h" #include "afb-hook.h" @@ -169,7 +168,6 @@ static void callreq_destroy_cb(struct afb_xreq *xreq) afb_context_disconnect(&callreq->xreq.context); json_object_put(callreq->xreq.json); - afb_cred_unref(callreq->xreq.cred); free(callreq); } @@ -282,24 +280,25 @@ static struct callreq *callreq_create( errno = ENOMEM; } else { afb_xreq_init(&callreq->xreq, &afb_calls_xreq_itf); - callreq->xreq.context.validated = 1; api2 = (char*)&callreq[1]; callreq->xreq.request.called_api = memcpy(api2, api, lenapi);; verb2 = &api2[lenapi]; callreq->xreq.request.called_verb = memcpy(verb2, verb, lenverb); callreq->xreq.json = args; callreq->mode = mode; - if (caller) { - export = afb_export_from_api_x3(caller->request.api); + if (!caller) + afb_export_context_init(export, &callreq->xreq.context); + else { + if (flags & afb_req_x2_subcall_api_session) + afb_export_context_init(export, &callreq->xreq.context); + else + afb_context_subinit(&callreq->xreq.context, &caller->context); if (flags & afb_req_x2_subcall_on_behalf) - callreq->xreq.cred = afb_cred_addref(caller->cred); + afb_context_on_behalf_other_context(&callreq->xreq.context, &caller->context); callreq->xreq.caller = caller; afb_xreq_unhooked_addref(caller); + export = afb_export_from_api_x3(caller->request.api); } - if (caller && (flags & afb_req_x2_subcall_api_session)) - afb_context_subinit(&callreq->xreq.context, &caller->context); - else - afb_export_context_init(export, &callreq->xreq.context); callreq->export = export; callreq->flags = flags; } diff --git a/src/afb-context.c b/src/afb-context.c index 36adebae..5235707f 100644 --- a/src/afb-context.c +++ b/src/afb-context.c @@ -26,8 +26,11 @@ #include "afb-session.h" #include "afb-context.h" #include "afb-token.h" +#include "afb-cred.h" +#include "afb-permission-text.h" +#include "verbose.h" -static void init_context(struct afb_context *context, struct afb_session *session, struct afb_token *token) +static void init_context(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred) { assert(session != NULL); @@ -37,6 +40,7 @@ static void init_context(struct afb_context *context, struct afb_session *sessio context->super = NULL; context->api_key = NULL; context->token = afb_token_addref(token); + context->credentials = afb_cred_addref(cred); /* check the token */ if (token != NULL) { @@ -47,28 +51,28 @@ static void init_context(struct afb_context *context, struct afb_session *sessio } } -void afb_context_init(struct afb_context *context, struct afb_session *session, struct afb_token *token) +void afb_context_init(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred) { - init_context(context, afb_session_addref(session), token); + init_context(context, afb_session_addref(session), token, cred); } -void afb_context_init_validated(struct afb_context *context, struct afb_session *session) +void afb_context_init_validated(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred) { - afb_context_init(context, session, NULL); + afb_context_init(context, session, token, cred); context->validated = 1; } void afb_context_subinit(struct afb_context *context, struct afb_context *super) { - context->session = super->session; + context->session = afb_session_addref(super->session); context->flags = 0; context->super = super; context->api_key = NULL; - context->token = super->token; - context->validated = super->validated; + context->token = afb_token_addref(super->token); + context->credentials = afb_cred_addref(super->credentials); } -int afb_context_connect(struct afb_context *context, const char *uuid, struct afb_token *token) +int afb_context_connect(struct afb_context *context, const char *uuid, struct afb_token *token, struct afb_cred *cred) { int created; struct afb_session *session; @@ -76,16 +80,16 @@ int afb_context_connect(struct afb_context *context, const char *uuid, struct af session = afb_session_get (uuid, AFB_SESSION_TIMEOUT_DEFAULT, &created); if (session == NULL) return -1; - init_context(context, session, token); + init_context(context, session, token, cred); if (created) { context->created = 1; } return 0; } -int afb_context_connect_validated(struct afb_context *context, const char *uuid) +int afb_context_connect_validated(struct afb_context *context, const char *uuid, struct afb_token *token, struct afb_cred *cred) { - int rc = afb_context_connect(context, uuid, NULL); + int rc = afb_context_connect(context, uuid, token, cred); if (!rc) context->validated = 1; return rc; @@ -93,16 +97,80 @@ int afb_context_connect_validated(struct afb_context *context, const char *uuid) void afb_context_disconnect(struct afb_context *context) { - if (context->session && !context->super) { - if (context->closing && !context->closed) { - afb_context_change_loa(context, 0); - afb_context_set(context, NULL, NULL); - context->closed = 1; + if (context->session && !context->super && context->closing && !context->closed) { + afb_context_change_loa(context, 0); + afb_context_set(context, NULL, NULL); + context->closed = 1; + } + afb_session_unref(context->session); + context->session = NULL; + afb_cred_unref(context->credentials); + context->credentials = NULL; + afb_token_unref(context->token); + context->token = NULL; +} + +void afb_context_change_cred(struct afb_context *context, struct afb_cred *cred) +{ + struct afb_cred *ocred = context->credentials; + if (ocred != cred) { + context->credentials = afb_cred_addref(cred); + afb_cred_unref(ocred); + } +} + +void afb_context_change_token(struct afb_context *context, struct afb_token *token) +{ + struct afb_token *otoken = context->token; + if (otoken != token) { + context->validated = 0; + context->invalidated = 0; + context->token = afb_token_addref(token); + afb_token_unref(otoken); + } +} + +const char *afb_context_on_behalf_export(struct afb_context *context) +{ + return context->credentials ? afb_cred_export(context->credentials) : NULL; +} + +int afb_context_on_behalf_import(struct afb_context *context, const char *exported) +{ + int rc; + struct afb_cred *imported, *ocred; + + if (!exported || !*exported) + rc = 0; + else { + if (afb_context_has_permission(context, afb_permission_on_behalf_credential)) { + imported = afb_cred_import(exported); + if (!imported) { + ERROR("Can't import on behalf credentials: %m"); + rc = -1; + } else { + ocred = context->credentials; + context->credentials = imported; + afb_cred_unref(ocred); + rc = 0; + } + } else { + ERROR("On behalf credentials refused"); + rc = -1; } - afb_token_unref(context->token); - afb_session_unref(context->session); - context->session = NULL; } + return rc; +} + +void afb_context_on_behalf_other_context(struct afb_context *context, struct afb_context *other) +{ + afb_context_change_cred(context, other->credentials); + afb_context_change_token(context, other->token); +} + +int afb_context_has_permission(struct afb_context *context, const char *permission) +{ + return afb_cred_has_permission(context->credentials, permission, context); } const char *afb_context_uuid(struct afb_context *context) diff --git a/src/afb-context.h b/src/afb-context.h index 83df1bbf..e3cf4151 100644 --- a/src/afb-context.h +++ b/src/afb-context.h @@ -19,11 +19,14 @@ struct afb_session; struct afb_token; +struct afb_cred; struct afb_context { - struct afb_session *session; - struct afb_token *token; + struct afb_session *session; /**< session */ + struct afb_token *token; /**< token */ + struct afb_cred *credentials; /**< credential */ + const void *api_key; struct afb_context *super; union { @@ -38,11 +41,11 @@ struct afb_context }; }; -extern void afb_context_init(struct afb_context *context, struct afb_session *session, struct afb_token *token); -extern void afb_context_init_validated(struct afb_context *context, struct afb_session *session); +extern void afb_context_init(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred); +extern void afb_context_init_validated(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred); extern void afb_context_subinit(struct afb_context *context, struct afb_context *super); -extern int afb_context_connect(struct afb_context *context, const char *uuid, struct afb_token *token); -extern int afb_context_connect_validated(struct afb_context *context, const char *uuid); +extern int afb_context_connect(struct afb_context *context, const char *uuid, struct afb_token *token, struct afb_cred *cred); +extern int afb_context_connect_validated(struct afb_context *context, const char *uuid, struct afb_token *token, struct afb_cred *cred); extern void afb_context_disconnect(struct afb_context *context); extern const char *afb_context_uuid(struct afb_context *context); @@ -50,6 +53,14 @@ extern void *afb_context_get(struct afb_context *context); extern int afb_context_set(struct afb_context *context, void *value, void (*free_value)(void*)); extern void *afb_context_make(struct afb_context *context, int replace, void *(*make_value)(void *closure), void (*free_value)(void *item), void *closure); +extern void afb_context_change_token(struct afb_context *context, struct afb_token *token); +extern void afb_context_change_cred(struct afb_context *context, struct afb_cred *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_close(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); diff --git a/src/afb-cred.c b/src/afb-cred.c index b6d698e9..b6e6feba 100644 --- a/src/afb-cred.c +++ b/src/afb-cred.c @@ -32,7 +32,6 @@ #include "afb-token.h" #include "verbose.h" - #define MAX_LABEL_LENGTH 1024 #if !defined(NO_DEFAULT_PEERCRED) && !defined(ADD_DEFAULT_PEERCRED) @@ -52,7 +51,6 @@ # 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"; @@ -222,23 +220,6 @@ struct afb_cred *afb_cred_import(const char *string) return cred; } -struct afb_cred *afb_cred_mixed_on_behalf_import(struct afb_cred *cred, struct afb_context *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); -} - /*********************************************************************************/ static const char *token_of_context(struct afb_context *context) { diff --git a/src/afb-cred.h b/src/afb-cred.h index 82d0aacb..46639408 100644 --- a/src/afb-cred.h +++ b/src/afb-cred.h @@ -43,6 +43,3 @@ extern int afb_cred_has_permission(struct afb_cred *cred, const char *permission extern const char *afb_cred_export(struct afb_cred *cred); extern struct afb_cred *afb_cred_import(const char *string); - -extern struct afb_cred *afb_cred_mixed_on_behalf_import(struct afb_cred *cred, struct afb_context *context, const char *exported); - diff --git a/src/afb-export.c b/src/afb-export.c index 0e06dae1..33891d31 100644 --- a/src/afb-export.c +++ b/src/afb-export.c @@ -41,7 +41,6 @@ #endif #include "afb-api-v3.h" #include "afb-common.h" -#include "afb-cred.h" #include "afb-evt.h" #include "afb-export.h" #include "afb-hook.h" @@ -1953,6 +1952,6 @@ void afb_export_process_xreq(struct afb_export *export, struct afb_xreq *xreq) void afb_export_context_init(struct afb_export *export, struct afb_context *context) { - afb_context_init_validated(context, export->session); + afb_context_init_validated(context, export->session, NULL, NULL); } diff --git a/src/afb-hook.c b/src/afb-hook.c index 1379caf8..909c5126 100644 --- a/src/afb-hook.c +++ b/src/afb-hook.c @@ -217,16 +217,18 @@ static void _hook_xreq_(const struct afb_xreq *xreq, const char *format, ...) static void hook_xreq_begin_cb(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq) { - if (!xreq->cred) + struct afb_cred *cred = xreq->context.credentials; + + if (!cred) _hook_xreq_(xreq, "BEGIN"); else _hook_xreq_(xreq, "BEGIN uid=%d=%s gid=%d pid=%d label=%s id=%s", - (int)xreq->cred->uid, - xreq->cred->user, - (int)xreq->cred->gid, - (int)xreq->cred->pid, - xreq->cred->label?:"(null)", - xreq->cred->id?:"(null)" + (int)cred->uid, + cred->user, + (int)cred->gid, + (int)cred->pid, + cred->label?:"(null)", + cred->id?:"(null)" ); } diff --git a/src/afb-hreq.c b/src/afb-hreq.c index 6be2ee5c..eb48a324 100644 --- a/src/afb-hreq.c +++ b/src/afb-hreq.c @@ -42,7 +42,6 @@ #include "afb-hreq.h" #include "afb-hsrv.h" #include "afb-session.h" -#include "afb-cred.h" #include "afb-token.h" #include "afb-error-text.h" #include "verbose.h" @@ -345,7 +344,6 @@ static void req_destroy(struct afb_xreq *xreq) json_object_put(hreq->json); free((char*)hreq->xreq.request.called_api); free((char*)hreq->xreq.request.called_verb); - afb_cred_unref(hreq->xreq.cred); free(hreq); } @@ -1017,7 +1015,7 @@ int afb_hreq_init_context(struct afb_hreq *hreq) if (token) afb_token_get(&tok, token); - return afb_context_connect(&hreq->xreq.context, uuid, tok); + return afb_context_connect(&hreq->xreq.context, uuid, tok, NULL); } int afb_hreq_init_cookie(int port, const char *path, int maxage) diff --git a/src/afb-permission-text.c b/src/afb-permission-text.c new file mode 100644 index 00000000..21069df8 --- /dev/null +++ b/src/afb-permission-text.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2017-2019 "IoT.bzh" + * Author: José Bollo + * + * 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 "afb-permission-text.h" + +const char afb_permission_on_behalf_credential[] = "urn:AGL:permission:*:partner:on-behalf-credentials"; diff --git a/src/afb-permission-text.h b/src/afb-permission-text.h new file mode 100644 index 00000000..1340f717 --- /dev/null +++ b/src/afb-permission-text.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2017-2019 "IoT.bzh" + * Author: José Bollo + * + * 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 + +extern const char afb_permission_on_behalf_credential[]; diff --git a/src/afb-stub-ws.c b/src/afb-stub-ws.c index 487873df..b3b2e58a 100644 --- a/src/afb-stub-ws.c +++ b/src/afb-stub-ws.c @@ -145,7 +145,6 @@ static void server_req_destroy_cb(struct afb_xreq *xreq) struct server_req *wreq = CONTAINER_OF_XREQ(struct server_req, xreq); afb_context_disconnect(&wreq->xreq.context); - afb_cred_unref(wreq->xreq.cred); json_object_put(wreq->xreq.json); afb_proto_ws_call_unref(wreq->call); afb_stub_ws_unref(wreq->stubws); @@ -526,10 +525,10 @@ static void server_on_call_cb(void *closure, struct afb_proto_ws_call *call, con wreq->call = call; /* init the context */ - afb_context_init(&wreq->xreq.context, session, token); + afb_context_init(&wreq->xreq.context, session, token, stubws->cred); + afb_context_on_behalf_import(&wreq->xreq.context, user_creds); /* makes the call */ - wreq->xreq.cred = afb_cred_mixed_on_behalf_import(stubws->cred, &wreq->xreq.context, user_creds); wreq->xreq.request.called_api = stubws->apiname; wreq->xreq.request.called_verb = verb; wreq->xreq.json = args; diff --git a/src/afb-supervision.c b/src/afb-supervision.c index 0515234f..259b256a 100644 --- a/src/afb-supervision.c +++ b/src/afb-supervision.c @@ -34,7 +34,6 @@ #define AFB_BINDING_VERSION 3 #include -#include "afb-cred.h" #include "afb-api.h" #include "afb-apiset.h" #include "afb-api-so-v2.h" @@ -394,8 +393,7 @@ static void on_supervision_call(void *closure, struct afb_xreq *xreq) if (!xapi) afb_xreq_reply_unknown_api(xreq); else { - afb_cred_unref(xreq->cred); - xreq->cred = NULL; + afb_context_change_cred(&xreq->context, NULL); xreq->request.called_api = api; xreq->request.called_verb = verb; xreq->json = json_object_get(sub); diff --git a/src/afb-trace.c b/src/afb-trace.c index 5f8ec64c..41721509 100644 --- a/src/afb-trace.c +++ b/src/afb-trace.c @@ -199,21 +199,23 @@ static void emit(void *closure, const struct afb_hookid *hookid, const char *typ static void hook_xreq(void *closure, const struct afb_hookid *hookid, const struct afb_xreq *xreq, const char *action, const char *format, ...) { - struct json_object *cred = NULL; + struct afb_cred *cred; + struct json_object *jcred = NULL; const char *session = NULL; va_list ap; if (xreq->context.session) session = afb_session_uuid(xreq->context.session); - if (xreq->cred) - wrap_json_pack(&cred, "{si ss si si ss* ss*}", - "uid", (int)xreq->cred->uid, - "user", xreq->cred->user, - "gid", (int)xreq->cred->gid, - "pid", (int)xreq->cred->pid, - "label", xreq->cred->label, - "id", xreq->cred->id + cred = xreq->context.credentials; + if (cred) + wrap_json_pack(&jcred, "{si ss si si ss* ss*}", + "uid", (int)cred->uid, + "user", cred->user, + "gid", (int)cred->gid, + "pid", (int)cred->pid, + "label", cred->label, + "id", cred->id ); va_start(ap, format); emit(closure, hookid, "request", "{si ss ss ss so* ss*}", format, ap, @@ -221,7 +223,7 @@ static void hook_xreq(void *closure, const struct afb_hookid *hookid, const stru "api", xreq->request.called_api, "verb", xreq->request.called_verb, "action", action, - "credentials", cred, + "credentials", jcred, "session", session); va_end(ap); } diff --git a/src/afb-ws-json1.c b/src/afb-ws-json1.c index 4f7991b6..ec22e1ed 100644 --- a/src/afb-ws-json1.c +++ b/src/afb-ws-json1.c @@ -213,14 +213,11 @@ static void aws_on_call_cb(void *closure, const char *api, const char *verb, str /* init the context */ afb_xreq_init(&wsreq->xreq, &afb_ws_json1_xreq_itf); - afb_context_init(&wsreq->xreq.context, ws->session, ws->token); - if (!wsreq->xreq.context.invalidated) - wsreq->xreq.context.validated = 1; + afb_context_init(&wsreq->xreq.context, ws->session, ws->token, ws->cred); /* fill and record the request */ afb_wsj1_msg_addref(msg); wsreq->msgj1 = msg; - wsreq->xreq.cred = afb_cred_addref(ws->cred); wsreq->xreq.request.called_api = api; wsreq->xreq.request.called_verb = verb; wsreq->xreq.json = afb_wsj1_msg_object_j(wsreq->msgj1); @@ -259,7 +256,6 @@ static void wsreq_destroy(struct afb_xreq *xreq) afb_context_disconnect(&wsreq->xreq.context); afb_wsj1_msg_unref(wsreq->msgj1); - afb_cred_unref(wsreq->xreq.cred); afb_ws_json1_unref(wsreq->aws); free(wsreq); } diff --git a/src/afb-xreq.c b/src/afb-xreq.c index 297681c5..c84d8a3e 100644 --- a/src/afb-xreq.c +++ b/src/afb-xreq.c @@ -287,13 +287,14 @@ static struct afb_stored_req *xreq_legacy_store_cb(struct afb_req_x2 *closure) static int xreq_has_permission_cb(struct afb_req_x2 *closure, const char *permission) { struct afb_xreq *xreq = xreq_from_req_x2(closure); - return afb_auth_has_permission(xreq, permission); + return afb_context_has_permission(&xreq->context, permission); } static char *xreq_get_application_id_cb(struct afb_req_x2 *closure) { struct afb_xreq *xreq = xreq_from_req_x2(closure); - return xreq->cred && xreq->cred->id ? strdup(xreq->cred->id) : NULL; + struct afb_cred *cred = xreq->context.credentials; + return cred && cred->id ? strdup(cred->id) : NULL; } static void *xreq_context_make_cb(struct afb_req_x2 *closure, int replace, void *(*create_value)(void*), void (*free_value)(void*), void *create_closure) @@ -305,20 +306,22 @@ static void *xreq_context_make_cb(struct afb_req_x2 *closure, int replace, void static int xreq_get_uid_cb(struct afb_req_x2 *closure) { struct afb_xreq *xreq = xreq_from_req_x2(closure); - return xreq->cred && xreq->cred->id ? (int)xreq->cred->uid : -1; + struct afb_cred *cred = xreq->context.credentials; + return cred && cred->id ? (int)cred->uid : -1; } static struct json_object *xreq_get_client_info_cb(struct afb_req_x2 *closure) { struct afb_xreq *xreq = xreq_from_req_x2(closure); + struct afb_cred *cred = xreq->context.credentials; struct json_object *r = json_object_new_object(); - if (xreq->cred && xreq->cred->id) { - json_object_object_add(r, "uid", json_object_new_int(xreq->cred->uid)); - json_object_object_add(r, "gid", json_object_new_int(xreq->cred->gid)); - json_object_object_add(r, "pid", json_object_new_int(xreq->cred->pid)); - json_object_object_add(r, "user", json_object_new_string(xreq->cred->user)); - json_object_object_add(r, "label", json_object_new_string(xreq->cred->label)); - json_object_object_add(r, "id", json_object_new_string(xreq->cred->id)); + if (cred && cred->id) { + json_object_object_add(r, "uid", json_object_new_int(cred->uid)); + json_object_object_add(r, "gid", json_object_new_int(cred->gid)); + json_object_object_add(r, "pid", json_object_new_int(cred->pid)); + json_object_object_add(r, "user", json_object_new_string(cred->user)); + json_object_object_add(r, "label", json_object_new_string(cred->label)); + json_object_object_add(r, "id", json_object_new_string(cred->id)); } if (xreq->context.session) { json_object_object_add(r, "uuid", json_object_new_string(afb_context_uuid(&xreq->context)?:"")); @@ -774,7 +777,7 @@ void afb_xreq_call_verb_v2(struct afb_xreq *xreq, const struct afb_verb_v2 *verb if (!verb) afb_xreq_reply_unknown_verb(xreq); else - if (afb_auth_check_and_set_session_x2(xreq, verb->session, verb->auth) >= 0) + if (afb_auth_check_and_set_session_x2(xreq, verb->auth, verb->session) > 0) verb->callback(xreq_to_req_x1(xreq)); } #endif @@ -784,7 +787,7 @@ void afb_xreq_call_verb_v3(struct afb_xreq *xreq, const struct afb_verb_v3 *verb if (!verb) afb_xreq_reply_unknown_verb(xreq); else - if (afb_auth_check_and_set_session_x2(xreq, verb->session, verb->auth) >= 0) + if (afb_auth_check_and_set_session_x2(xreq, verb->auth, verb->session) > 0) verb->callback(xreq_to_req_x2(xreq)); } @@ -901,6 +904,6 @@ end: const char *xreq_on_behalf_cred_export(struct afb_xreq *xreq) { - return xreq->caller ? afb_cred_export(xreq->cred) : NULL; + return afb_context_on_behalf_export(&xreq->context); } diff --git a/src/afb-xreq.h b/src/afb-xreq.h index 03aeef4c..11e19954 100644 --- a/src/afb-xreq.h +++ b/src/afb-xreq.h @@ -59,7 +59,6 @@ struct afb_xreq int hookflags; /**< flags for hooking */ int hookindex; /**< hook index of the request if hooked */ #endif - struct afb_cred *cred; /**< client credential if revelant */ struct afb_xreq *caller; /**< caller request if any */ }; diff --git a/src/main-afb-daemon.c b/src/main-afb-daemon.c index 077c7163..a8d99ff5 100644 --- a/src/main-afb-daemon.c +++ b/src/main-afb-daemon.c @@ -662,7 +662,7 @@ static void startup_call_current(struct startup_req *sreq) json = strchr(verb, ':'); if (json) { afb_xreq_init(&sreq->xreq, &startup_xreq_itf); - afb_context_init_validated(&sreq->xreq.context, sreq->session); + afb_context_init_validated(&sreq->xreq.context, sreq->session, NULL, NULL); sreq->api = strndup(api, verb - api); sreq->verb = strndup(verb + 1, json - verb - 1); sreq->xreq.request.called_api = sreq->api; -- cgit 1.2.3-korg