diff options
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/afb-api-dbus.c | 10 | ||||
-rw-r--r-- | src/afb-auth.c | 29 | ||||
-rw-r--r-- | src/afb-auth.h | 9 | ||||
-rw-r--r-- | src/afb-calls.c | 19 | ||||
-rw-r--r-- | src/afb-context.c | 108 | ||||
-rw-r--r-- | src/afb-context.h | 23 | ||||
-rw-r--r-- | src/afb-cred.c | 19 | ||||
-rw-r--r-- | src/afb-cred.h | 3 | ||||
-rw-r--r-- | src/afb-export.c | 3 | ||||
-rw-r--r-- | src/afb-hook.c | 16 | ||||
-rw-r--r-- | src/afb-hreq.c | 4 | ||||
-rw-r--r-- | src/afb-permission-text.c | 20 | ||||
-rw-r--r-- | src/afb-permission-text.h | 20 | ||||
-rw-r--r-- | src/afb-stub-ws.c | 5 | ||||
-rw-r--r-- | src/afb-supervision.c | 4 | ||||
-rw-r--r-- | src/afb-trace.c | 22 | ||||
-rw-r--r-- | src/afb-ws-json1.c | 6 | ||||
-rw-r--r-- | src/afb-xreq.c | 29 | ||||
-rw-r--r-- | src/afb-xreq.h | 1 | ||||
-rw-r--r-- | src/main-afb-daemon.c | 2 |
21 files changed, 222 insertions, 131 deletions
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 <afb/afb-binding.h> #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 <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 "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 <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 + +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 <afb/afb-binding.h> -#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; |