Skip to content

Commit

Permalink
oc_acl: refactor and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielius1922 committed Apr 20, 2024
1 parent 7ea659a commit 5ea3443
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 58 deletions.
173 changes: 115 additions & 58 deletions security/oc_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,73 +109,115 @@ acl_get_new_aceid(size_t device)
return aceid;
}

bool
oc_sec_encode_acl(size_t device, oc_interface_mask_t iface_mask,
bool to_storage)
#define OC_ACL_PROP_UUID "uuid"
#define OC_ACL_PROP_ROLE "role"
#define OC_ACL_PROP_AUTHORITY "authority"
#define OC_ACL_PROP_CONNTYPE "conntype"
#define OC_ACL_PROP_RESOURCES "resources"

static oc_string_view_t
ace_connection_type_to_str(oc_ace_connection_type_t type)
{
char uuid[OC_UUID_LEN];
oc_rep_start_root_object();
if (to_storage || iface_mask & OC_IF_BASELINE) {
oc_process_baseline_interface(
oc_core_get_resource_by_index(OCF_SEC_ACL, device));
if (type == OC_CONN_AUTH_CRYPT) {
return OC_STRING_VIEW(OC_CONN_AUTH_CRYPT_STR);
}
oc_rep_set_array(root, aclist2);
const oc_sec_ace_t *sub = oc_list_head(g_aclist[device].subjects);
if (type == OC_CONN_ANON_CLEAR) {
return OC_STRING_VIEW(OC_CONN_ANON_CLEAR_STR);
}
return OC_STRING_VIEW_NULL;
}

while (sub != NULL) {
oc_rep_object_array_start_item(aclist2);
oc_rep_set_object(aclist2, subject);
switch (sub->subject_type) {
case OC_SUBJECT_UUID:
oc_uuid_to_str(&sub->subject.uuid, uuid, OC_UUID_LEN);
oc_rep_set_text_string(subject, uuid, uuid);
break;
case OC_SUBJECT_ROLE:
oc_rep_set_text_string(subject, role, oc_string(sub->subject.role.role));
if (oc_string_len(sub->subject.role.authority) > 0) {
oc_rep_set_text_string(subject, authority,
oc_string(sub->subject.role.authority));
}
break;
case OC_SUBJECT_CONN: {
switch (sub->subject.conn) {
case OC_CONN_AUTH_CRYPT:
oc_rep_set_text_string(subject, conntype, "auth-crypt");
static void
acl_encode_subject(CborEncoder *encoder, const oc_sec_ace_t *sub)
{
if (sub->subject_type == OC_SUBJECT_UUID) {
char uuid[OC_UUID_LEN];
int len = oc_uuid_to_str_v1(&sub->subject.uuid, uuid, OC_UUID_LEN);
assert(len > 0);
oc_string_view_t key = OC_STRING_VIEW(OC_ACL_PROP_UUID);
g_err |= oc_rep_object_set_text_string(encoder, key.data, key.length, uuid,
(size_t)len);
return;
}

if (sub->subject_type == OC_SUBJECT_ROLE) {
oc_string_view_t role_key = OC_STRING_VIEW(OC_ACL_PROP_ROLE);
g_err |= oc_rep_object_set_text_string(
encoder, role_key.data, role_key.length,
oc_string(sub->subject.role.role),
oc_string_len_unsafe(sub->subject.role.role));
if (!oc_string_is_empty(&sub->subject.role.authority)) {
oc_string_view_t authority_key = OC_STRING_VIEW(OC_ACL_PROP_AUTHORITY);
g_err |= oc_rep_object_set_text_string(
encoder, authority_key.data, authority_key.length,
oc_string(sub->subject.role.authority),
oc_string_len_unsafe(sub->subject.role.authority));
}
return;
}

if (sub->subject_type == OC_SUBJECT_CONN) {
oc_string_view_t conntype_key = OC_STRING_VIEW(OC_ACL_PROP_CONNTYPE);
oc_string_view_t conntype = ace_connection_type_to_str(sub->subject.conn);
g_err |= oc_rep_object_set_text_string(encoder, conntype_key.data,
conntype_key.length, conntype.data,
conntype.length);
return;
}
}

static void
acl_encode_subject_resources(CborEncoder *encoder, const oc_ace_res_t *res)
{
oc_string_view_t key = OC_STRING_VIEW(OC_ACL_PROP_RESOURCES);
g_err |= oc_rep_encode_text_string(encoder, key.data, key.length);
oc_rep_begin_array(encoder, resources);
for (; res != NULL; res = res->next) {
oc_rep_object_array_start_item(resources);
size_t href_len = oc_string_len(res->href);
if (href_len > 0) {
oc_rep_set_text_string_v1(resources, href, oc_string(res->href),
href_len);
} else {
switch (res->wildcard) {
case OC_ACE_WC_ALL_SECURED:
oc_rep_set_text_string_v1(resources, wc, OC_ACE_WC_ALL_SECURED_STR,
OC_CHAR_ARRAY_LEN(OC_ACE_WC_ALL_SECURED_STR));
break;
case OC_CONN_ANON_CLEAR:
oc_rep_set_text_string(subject, conntype, "anon-clear");
case OC_ACE_WC_ALL_PUBLIC:
oc_rep_set_text_string_v1(resources, wc, OC_ACE_WC_ALL_PUBLIC_STR,
OC_CHAR_ARRAY_LEN(OC_ACE_WC_ALL_PUBLIC_STR));
break;
case OC_ACE_WC_ALL:
oc_rep_set_text_string_v1(resources, wc, OC_ACE_WC_ALL_STR,
OC_CHAR_ARRAY_LEN(OC_ACE_WC_ALL_STR));
break;
default:
break;
}
} break;
}
oc_rep_object_array_end_item(resources);
}
oc_rep_end_array(encoder, resources);
}

static void
acl_encode_subjects(oc_list_t subjects, bool to_storage)
{
oc_rep_open_array(root, aclist2);
const oc_sec_ace_t *sub = oc_list_head(subjects);

while (sub != NULL) {
oc_rep_object_array_start_item(aclist2);

oc_rep_open_object(aclist2, subject);
acl_encode_subject(oc_rep_object(subject), sub);
oc_rep_close_object(aclist2, subject);

oc_ace_res_t *res = (oc_ace_res_t *)oc_list_head(sub->resources);
oc_rep_set_array(aclist2, resources);

while (res != NULL) {
oc_rep_object_array_start_item(resources);
if (oc_string_len(res->href) > 0) {
oc_rep_set_text_string(resources, href, oc_string(res->href));
} else {
switch (res->wildcard) {
case OC_ACE_WC_ALL_SECURED:
oc_rep_set_text_string(resources, wc, OC_ACE_WC_ALL_SECURED_STR);
break;
case OC_ACE_WC_ALL_PUBLIC:
oc_rep_set_text_string(resources, wc, OC_ACE_WC_ALL_PUBLIC_STR);
break;
case OC_ACE_WC_ALL:
oc_rep_set_text_string(resources, wc, OC_ACE_WC_ALL_STR);
break;
default:
break;
}
}
oc_rep_object_array_end_item(resources);
res = res->next;
}
oc_rep_close_array(aclist2, resources);
acl_encode_subject_resources(
oc_rep_object(aclist2),
(const oc_ace_res_t *)oc_list_head(sub->resources));

oc_rep_set_uint(aclist2, permission, sub->permission);
oc_rep_set_int(aclist2, aceid, sub->aceid);
if (to_storage) {
Expand All @@ -187,6 +229,21 @@ oc_sec_encode_acl(size_t device, oc_interface_mask_t iface_mask,
sub = sub->next;
}
oc_rep_close_array(root, aclist2);
}

bool
oc_sec_encode_acl(size_t device, oc_interface_mask_t iface_mask,
bool to_storage)
{
oc_rep_start_root_object();
if (to_storage || iface_mask & OC_IF_BASELINE) {
oc_process_baseline_interface(
oc_core_get_resource_by_index(OCF_SEC_ACL, device));
}

acl_encode_subjects(g_aclist[device].subjects, to_storage);

char uuid[OC_UUID_LEN];
oc_uuid_to_str(&g_aclist[device].rowneruuid, uuid, OC_UUID_LEN);
oc_rep_set_text_string(root, rowneruuid, uuid);
oc_rep_end_root_object();
Expand Down
11 changes: 11 additions & 0 deletions security/oc_acl_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,22 @@ extern "C" {
#define OCF_SEC_ACL_URI "/oic/sec/acl2"
#define OCF_SEC_ACL_RT "oic.r.acl2"

#define OC_CONN_AUTH_CRYPT_STR "auth-crypt"
#define OC_CONN_ANON_CLEAR_STR "anon-clear"

/** @brief Allocate and initialize global variables */
void oc_sec_acl_init(void);

/** @brief Deallocate global variables */
void oc_sec_acl_free(void);

/** @brief Reset the ACL resource for given device to default values. */
void oc_sec_acl_default(size_t device);

/** @brief Encode the ACL resource to root encoder. */
bool oc_sec_encode_acl(size_t device, oc_interface_mask_t iface_mask,
bool to_storage);

bool oc_sec_decode_acl(const oc_rep_t *rep, bool from_storage, size_t device,
oc_sec_on_apply_acl_cb_t on_apply_ace_cb,
void *on_apply_ace_data);
Expand Down

0 comments on commit 5ea3443

Please sign in to comment.