From 8b9160f56585cfef198c3399f655e2eb33b02f87 Mon Sep 17 00:00:00 2001 From: Andrii Shtompel Date: Tue, 13 Sep 2016 01:25:29 +0900 Subject: [PATCH] ACL fix for supporting few ACEs Verified using 41 request (read user input, convert it to OCpayload, parse it and save to db) [Patch #5] Correctly clean-up single-linked list in 41 request Change-Id: Id2da459f776ae756cff4408688143946c7085de9 Signed-off-by: Andrii Shtompel Reviewed-on: https://gerrit.iotivity.org/gerrit/12041 Tested-by: jenkins-iotivity Reviewed-by: Randeep Singh (cherry picked from commit 552951a50ee2264ebf6723c0c08cdd7c356fd14d) Reviewed-on: https://gerrit.iotivity.org/gerrit/11707 --- .../csdk/security/include/internal/aclresource.h | 15 +++ .../provisioning/sample/cloud/cloudWrapper.c | 110 ++++++++++++--------- .../csdk/security/provisioning/src/cloud/aclid.c | 44 ++++++--- resource/csdk/security/src/aclresource.c | 98 ++++++++++++++++-- 4 files changed, 197 insertions(+), 70 deletions(-) diff --git a/resource/csdk/security/include/internal/aclresource.h b/resource/csdk/security/include/internal/aclresource.h index 3596377..93661b2 100644 --- a/resource/csdk/security/include/internal/aclresource.h +++ b/resource/csdk/security/include/internal/aclresource.h @@ -83,6 +83,13 @@ OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource); void DeleteACLList(OicSecAcl_t* acl); /** + * This function frees OicSecRsrc_t object's fields and object itself. + * + * @param rsrc instance of @ref OicSecRsrc_t structure to be deleted. + */ +void FreeRsrc(OicSecRsrc_t *rsrc); + +/** * Internal function to duplicate the ACE instance. * * @param ace instance of @ref OicSecAce_t structure to be duplicated. @@ -144,6 +151,14 @@ OCStackResult GetAclRownerId(OicUuid_t *rowneruuid); */ OicSecAcl_t* CBORPayloadToAcl2(const uint8_t *cborPayload, const size_t size); +/** + * This function prints ACL to stdin + * For debug purposes only + * + * @param acl acl to print + */ +void printACL(const OicSecAcl_t* acl); + #ifdef __cplusplus } #endif diff --git a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c index a94713e..60b9d86 100644 --- a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c +++ b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c @@ -2,6 +2,8 @@ #include "occloudprovisioning.h" #include "oic_malloc.h" #include "oic_string.h" +#include "srmutility.h" +#include "utlist.h" #include "utils.h" @@ -227,6 +229,43 @@ exit: return 0; } +/** + * Frees particular cloudAce object + * + * @param[in] ace ace object to free + * */ +static void freeCloudAce(cloudAce_t *ace) +{ + OICFree(ace->aceId); + + //Clean Resources + OicSecRsrc_t* rsrc = NULL; + OicSecRsrc_t* tmpRsrc = NULL; + LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc) + { + LL_DELETE(ace->resources, rsrc); + FreeRsrc(rsrc); + } + + OICFree(ace); +} + +/** + * Deletes cloudAce list + * + * @param[in] ace aces list to delete + * */ +static void deleteCloudAceList(cloudAce_t *aces) +{ + cloudAce_t *ace = NULL; + cloudAce_t *tmpAce = NULL; + LL_FOREACH_SAFE(aces, ace, tmpAce) + { + LL_DELETE(aces, ace); + freeCloudAce(ace); + } +} + OCStackResult OCWrapperCertificateIssueRequest(const OCDevAddr *endPoint, OCCloudResponseCB callback) { return OCCloudCertificateIssueRequest(NULL, endPoint, callback); @@ -314,25 +353,24 @@ OCStackResult OCWrapperAclIndividualGetInfo(const OCDevAddr *endPoint, OCCloudRe OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloudResponseCB callback) { OCStackResult result = OC_STACK_NO_MEMORY; - int i = 0, j = 0; char aclid[MAX_ID_LENGTH] = { 0 }; - readString(aclid, sizeof(aclid), "ace id", ACL_ID_EXAMPLE); + readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE); int acllist_count = 0; readInteger(&acllist_count, "acl list count", "1"); - cloudAce_t *aces = OICCalloc(acllist_count, sizeof(cloudAce_t)); - if (!aces) - { - OIC_LOG(ERROR, TAG, "Can't allocate memory for aces"); - goto exit; - } + cloudAce_t *aces = NULL; - for (i = 0; i < acllist_count; i++) + for (int i = 0; i < acllist_count; i++) { - cloudAce_t *ace = &aces[i]; - if (i != acllist_count - 1) ace->next = &aces[i + 1]; + cloudAce_t *ace = OICCalloc(1, sizeof(cloudAce_t)); + if (!ace) + { + OIC_LOG(ERROR, TAG, "Can't allocate memory for ace"); + goto exit; + } + LL_APPEND(aces, ace); char aceid[MAX_ID_LENGTH] = { 0 }; char subjectuuid[MAX_ID_LENGTH] = { 0 }; @@ -340,29 +378,30 @@ OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloud int permission = 0; readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE); - readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE); + do + { + readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE); + } while (OC_STACK_OK != ConvertStrToUuid(subjectuuid, &ace->subjectuuid)); + readInteger(&stype, "subject type", "0 – Device, 1 – User, 2 - Group"); readInteger(&permission, "permission", "6"); ace->aceId = OICStrdup(aceid); ace->stype = stype; ace->permission = permission; - memcpy(&ace->subjectuuid, subjectuuid, sizeof(OicUuid_t)); int reslist_count = 0; readInteger(&reslist_count, "resources list count", "1"); - ace->resources = OICCalloc(reslist_count, sizeof(OicSecRsrc_t)); - if (!ace->resources) + for (int i = 0; i < reslist_count; i++) { - OIC_LOG(ERROR, TAG, "Can't allocate memory for resources"); - goto exit; - } - - for (j = 0; j < reslist_count; j++) - { - OicSecRsrc_t *res = &ace->resources[j]; - if (j != reslist_count - 1) res->next = &ace->resources[j + 1]; + OicSecRsrc_t *res = OICCalloc(1, sizeof(OicSecRsrc_t)); + if (!res) + { + OIC_LOG(ERROR, TAG, "Can't allocate memory for res"); + goto exit; + } + LL_APPEND(ace->resources, res); char href[32] = { 0 }; readString(href, sizeof(href), "href", RESOURCE_URI_EXAMPLE); @@ -383,30 +422,7 @@ OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloud result = OCCloudAclIndividualUpdateAce(NULL, aclid, aces, endPoint, callback); exit: - if (aces) - { - for (int k = 0; k < i; k++) - { - cloudAce_t *ace = &aces[k]; - OICFree(ace->aceId); - - if (ace->resources) - { - for (int l = 0; l < j; l++) - { - OicSecRsrc_t *res = &ace->resources[l]; - OICFree(res->href); - - stringArray_t rt = {.array = res->types, .length = res->typeLen}; - clearStringArray(&rt); - - stringArray_t _if = {.array = res->interfaces, .length = res->interfaceLen}; - clearStringArray(&_if); - } - } - - } - } + deleteCloudAceList(aces); return result; } diff --git a/resource/csdk/security/provisioning/src/cloud/aclid.c b/resource/csdk/security/provisioning/src/cloud/aclid.c index 10bcb32..c85c478 100644 --- a/resource/csdk/security/provisioning/src/cloud/aclid.c +++ b/resource/csdk/security/provisioning/src/cloud/aclid.c @@ -5,10 +5,12 @@ #include "ocstack.h" #include "ocpayload.h" #include "pmutility.h" +#include "srmutility.h" #include "cacommonutil.h" #include "aclresource.h" #include "ocpayloadcbor.h" #include "payload_logging.h" +#include "utlist.h" #define TAG "CLOUD-ACL-ID" @@ -170,6 +172,8 @@ static OCStackResult handleAclGetInfoResponse(void *ctx, void **data, OCClientRe goto exit; } + printACL(acl); + result = InstallNewACL2(acl); if (result != OC_STACK_OK) { @@ -231,10 +235,10 @@ OCStackResult OCCloudAclIndividualUpdateAce(void* ctx, } int acllist_count = 0; - if (aces) + //code below duplicates LL_COUNT, implemented in newer version of utlist.h { - cloudAce_t *ace = (cloudAce_t *)&aces[acllist_count++]; - while (ace->next) + cloudAce_t *ace = (cloudAce_t*)aces; + while (ace) { ace = ace->next; acllist_count++; @@ -248,7 +252,10 @@ OCStackResult OCCloudAclIndividualUpdateAce(void* ctx, goto no_memory; } - for (int i = 0; i < acllist_count; i++) + i = 0; + cloudAce_t *ace = NULL; + + LL_FOREACH((cloudAce_t*)aces, ace) { OCRepPayload *payload = OCRepPayloadCreate(); if (!payload) @@ -256,20 +263,26 @@ OCStackResult OCCloudAclIndividualUpdateAce(void* ctx, OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]"); goto no_memory; } - helperPayload[i] = payload; + helperPayload[i++] = payload; - const cloudAce_t *ace = &aces[i]; + char *uuid = NULL; + if (OC_STACK_OK != ConvertUuidToStr(&ace->subjectuuid, &uuid)) + { + OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string"); + } OCRepPayloadSetPropString(payload, OC_RSRVD_ACE_ID, ace->aceId); - OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)ace->subjectuuid.id); + OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)uuid); OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype); OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission); + OICFree(uuid); + int reslist_count = 0; - if (ace->resources) + //code below duplicates LL_COUNT, implemented in newer version of utlist.h { - OicSecRsrc_t *res = &ace->resources[reslist_count++]; - while (res->next) + OicSecRsrc_t *res = ace->resources; + while (res) { res = res->next; reslist_count++; @@ -282,17 +295,18 @@ OCStackResult OCCloudAclIndividualUpdateAce(void* ctx, goto no_memory; } - for (int j = 0; j < reslist_count; j++) + j = 0; + OicSecRsrc_t *res = NULL; + + LL_FOREACH(ace->resources, res) { OCRepPayload *payload = OCRepPayloadCreate(); if (!payload) { - OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload"); + OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload2[j]"); goto no_memory; } - helperPayload2[j] = payload; - - const OicSecRsrc_t *res = &ace->resources[j]; + helperPayload2[j++] = payload; OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href); diff --git a/resource/csdk/security/src/aclresource.c b/resource/csdk/security/src/aclresource.c index 95682fb..74646bc 100644 --- a/resource/csdk/security/src/aclresource.c +++ b/resource/csdk/security/src/aclresource.c @@ -63,10 +63,7 @@ static const uint16_t CBOR_SIZE = 2048; static OicSecAcl_t *gAcl = NULL; static OCResourceHandle gAclHandle = NULL; -/** - * This function frees OicSecRsrc_t object's fields and object itself. - */ -static void FreeRsrc(OicSecRsrc_t *rsrc) +void FreeRsrc(OicSecRsrc_t *rsrc) { //Clean each member of resource OICFree(rsrc->href); @@ -2187,6 +2184,80 @@ const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t ** return NULL; } +void printACL(const OicSecAcl_t* acl) +{ + OIC_LOG(INFO, TAG, "Print ACL:"); + + char *rowner = NULL; + if (OC_STACK_OK == ConvertUuidToStr(&acl->rownerID, &rowner)) + { + OIC_LOG_V(INFO, TAG, "rowner id = %s", rowner); + } + else + { + OIC_LOG(ERROR, TAG, "Can't convert rowner uuid to string"); + } + OICFree(rowner); + + const OicSecAce_t *ace = acl->aces; + int ace_count = 0; + while (ace) + { + ace_count++; + OIC_LOG_V(INFO, TAG, "Print ace[%d]:", ace_count); + + OIC_LOG_V(INFO, TAG, "ace permission = %d", ace->permission); + + char *subjectuuid = NULL; + if (OC_STACK_OK == ConvertUuidToStr(&ace->subjectuuid, &subjectuuid)) + { + OIC_LOG_V(INFO, TAG, "ace subject uuid = %s", subjectuuid); + } + else + { + OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string"); + } + OICFree(subjectuuid); + + OicSecRsrc_t *res = ace->resources; + int res_count = 0; + while (res) + { + res_count++; + OIC_LOG_V(INFO, TAG, "Print resources[%d]:", res_count); + + OIC_LOG_V(INFO, TAG, "href = %s", res->href); + + for (size_t i = 0; i < res->typeLen; i++) + { + OIC_LOG_V(INFO, TAG, "if[%zu] = %s", i, res->types[i]); + } + for (size_t i = 0; i < res->interfaceLen; i++) + { + OIC_LOG_V(INFO, TAG, "if[%zu] = %s", i, res->interfaces[i]); + } + + res= res->next; + } + + OicSecValidity_t *vals = ace->validities; + int vals_count = 0; + while (vals) + { + vals_count++; + OIC_LOG_V(INFO, TAG, "Print validities[%d]:", vals_count); + + OIC_LOG_V(INFO, TAG, "period = %s", vals->period); + for (size_t i = 0; i < vals->recurrenceLen; i++) + { + OIC_LOG_V(INFO, TAG, "recurrences[%zu] = %s", i, vals->recurrences[i]); + } + } + + ace = ace->next; + } +} + OCStackResult InstallNewACL2(const OicSecAcl_t* acl) { OCStackResult ret = OC_STACK_ERROR; @@ -2196,12 +2267,23 @@ OCStackResult InstallNewACL2(const OicSecAcl_t* acl) return OC_STACK_INVALID_PARAM; } - // Append the new ACL to existing ACL - OicSecAce_t* newAce = NULL; - LL_FOREACH(acl->aces, newAce) + // Append the new ACE to existing ACE list + // Can't use LL_APPEND because it sets ace->next to NULL + OicSecAce_t* ace = gAcl->aces; + if (ace) { - LL_APPEND(gAcl->aces, newAce); + while (ace->next) + { + ace = ace->next; + } + ace->next = acl->aces; } + else + { + gAcl->aces = acl->aces; + } + + printACL(gAcl); size_t size = 0; uint8_t *payload = NULL; -- 2.7.4