aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/afb-api-dbus.c10
-rw-r--r--src/afb-auth.c29
-rw-r--r--src/afb-auth.h9
-rw-r--r--src/afb-calls.c19
-rw-r--r--src/afb-context.c108
-rw-r--r--src/afb-context.h23
-rw-r--r--src/afb-cred.c19
-rw-r--r--src/afb-cred.h3
-rw-r--r--src/afb-export.c3
-rw-r--r--src/afb-hook.c16
-rw-r--r--src/afb-hreq.c4
-rw-r--r--src/afb-permission-text.c20
-rw-r--r--src/afb-permission-text.h20
-rw-r--r--src/afb-stub-ws.c5
-rw-r--r--src/afb-supervision.c4
-rw-r--r--src/afb-trace.c22
-rw-r--r--src/afb-ws-json1.c6
-rw-r--r--src/afb-xreq.c29
-rw-r--r--src/afb-xreq.h1
-rw-r--r--src/main-afb-daemon.c2
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;