/*
- * Copyright (C) 2017 "IoT.bzh"
+ * Copyright (C) 2015-2020 "IoT.bzh"
* Author: José Bollo <jose.bollo@iot.bzh>
*
* Licensed under the Apache License, Version 2.0 (the "License");
#define _GNU_SOURCE
#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include "afb-cred.h"
+#include "verbose.h"
#define MAX_LABEL_LENGTH 1024
# define DEFAULT_PEERCRED_PID 0 /* no process */
#endif
+static char export_format[] = "%x:%x:%x-%s";
+static char import_format[] = "%x:%x:%x-%n";
+
static struct afb_cred *current;
static struct afb_cred *mkcred(uid_t uid, gid_t gid, pid_t pid, const char *label, size_t size)
cred->uid = uid;
cred->gid = gid;
cred->pid = pid;
+ cred->exported = NULL;
dest = (char*)(&cred[1]);
cred->user = dest;
while(i)
void afb_cred_unref(struct afb_cred *cred)
{
if (cred && !__atomic_sub_fetch(&cred->refcount, 1, __ATOMIC_RELAXED)) {
- if (cred != current)
- free(cred);
- else
+ if (cred == current)
cred->refcount = 1;
+ else {
+ free((void*)cred->exported);
+ free(cred);
+ }
}
}
return afb_cred_addref(current);
}
+const char *afb_cred_export(struct afb_cred *cred)
+{
+ int rc;
+
+ if (!cred->exported) {
+ rc = asprintf((char**)&cred->exported,
+ export_format,
+ (int)cred->uid,
+ (int)cred->gid,
+ (int)cred->pid,
+ cred->label);
+ if (rc < 0) {
+ errno = ENOMEM;
+ cred->exported = NULL;
+ }
+ }
+ return cred->exported;
+}
+
+struct afb_cred *afb_cred_import(const char *string)
+{
+ struct afb_cred *cred;
+ int rc, uid, gid, pid, pos;
+
+ rc = sscanf(string, import_format, &uid, &gid, &pid, &pos);
+ if (rc == 3)
+ cred = afb_cred_create((uid_t)uid, (gid_t)gid, (pid_t)pid, &string[pos]);
+ else {
+ errno = EINVAL;
+ cred = NULL;
+ }
+ return cred;
+}