X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fsecurity%2Fsrc%2Faclresource.c;h=dc4b87426dde77e852cbbfcb5b3735da8bf6f2f0;hb=d2124971f17b1767127a7241ecc95d00633e5f3e;hp=450123fc454422b43a5056aa3c49df457305cabc;hpb=340918a789806270515ebef6723a058f6c9b3f7d;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/security/src/aclresource.c b/resource/csdk/security/src/aclresource.c index 450123f..dc4b874 100644 --- a/resource/csdk/security/src/aclresource.c +++ b/resource/csdk/security/src/aclresource.c @@ -42,11 +42,12 @@ #include "resourcemanager.h" #include "srmutility.h" #include "psinterface.h" +#include "ocpayloadcbor.h" #include "security_internals.h" -#define TAG "SRM-ACL" -#define NUMBER_OF_SEC_PROV_RSCS 4 +#define TAG "OIC_SRM_ACL" +#define NUMBER_OF_SEC_PROV_RSCS 3 #define NUMBER_OF_DEFAULT_SEC_RSCS 2 #define STRING_UUID_SIZE (UUID_LENGTH * 2 + 5) @@ -57,15 +58,12 @@ static const uint8_t ACL_RESOURCE_MAP_SIZE = 3; // CborSize is the default cbor payload size being used. -static const uint16_t CBOR_SIZE = 2048; +static const uint16_t CBOR_SIZE = 2048*8; 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); @@ -134,6 +132,10 @@ static void FreeACE(OicSecAce_t *ace) validity = NULL; } +#ifdef MULTIPLE_OWNER + OICFree(ace->eownerID); +#endif + //Clean ACE OICFree(ace); ace = NULL; @@ -188,6 +190,7 @@ OicSecAce_t* DuplicateACE(const OicSecAce_t* ace) newRsrc->rel = (char*)OICMalloc(sizeof(char) * allocateSize); VERIFY_NON_NULL(TAG, newRsrc->rel, ERROR); OICStrcpy(newRsrc->rel, allocateSize, rsrc->rel); + newRsrc->rel[allocateSize - 1] = '\0'; } if(rsrc->types && 0 < rsrc->typeLen) @@ -254,6 +257,18 @@ OicSecAce_t* DuplicateACE(const OicSecAce_t* ace) } } +#ifdef MULTIPLE_OWNER + if (ace->eownerID) + { + if (NULL == newAce->eownerID) + { + newAce->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t)); + VERIFY_NON_NULL(TAG, (newAce->eownerID), ERROR); + } + memcpy(newAce->eownerID->id, ace->eownerID->id, sizeof(ace->eownerID->id)); + } +#endif + newAce->next = NULL; } @@ -348,7 +363,15 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, siz { aclMapSize++; } + validityElts = validityElts->next; + } + +#ifdef MULTIPLE_OWNER + if(ace->eownerID) + { + aclMapSize++; } +#endif //MULTIPLE_OWNER cborEncoderResult = cbor_encoder_create_map(&acesArray, &oicSecAclMap, aclMapSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Map"); @@ -540,6 +563,22 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, siz VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validities Array."); } +#ifdef MULTIPLE_OWNER + // Eownerid -- Not Mandatory + if(ace->eownerID) + { + char *eowner = NULL; + cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_EOWNERID_NAME, + strlen(OIC_JSON_EOWNERID_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding eownerId Name Tag."); + ret = ConvertUuidToStr(ace->eownerID, &eowner); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, eowner, strlen(eowner)); + OICFree(eowner); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value."); + } +#endif //MULTIPLE_OWNER + cborEncoderResult = cbor_encoder_close_container(&acesArray, &oicSecAclMap); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Map."); } @@ -604,7 +643,7 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, siz if (CborNoError == cborEncoderResult) { OIC_LOG(DEBUG, TAG, "AclToCBORPayload Successed"); - *size = encoder.ptr - outPayload; + *size = cbor_encoder_get_buffer_size(&encoder, outPayload); *payload = outPayload; ret = OC_STACK_OK; } @@ -616,7 +655,7 @@ exit: // reallocate and try again! OICFree(outPayload); // Since the allocated initial memory failed, double the memory. - cborLen += encoder.ptr - encoder.end; + cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end); cborEncoderResult = CborNoError; ret = AclToCBORPayload(secAcl, payload, &cborLen); *size = cborLen; @@ -636,6 +675,311 @@ exit: // This function converts CBOR format to ACL data. // Caller needs to invoke 'free' when done using +// It parses { "aclist" : [ { ... } ] } instead of { "aclist" : { "aces" : [ ] } } +OicSecAcl_t* CBORPayloadToAcl2(const uint8_t *cborPayload, const size_t size) +{ + if (NULL == cborPayload || 0 == size) + { + return NULL; + } + OCStackResult ret = OC_STACK_ERROR; + CborValue aclCbor = { .parser = NULL }; + CborParser parser = { .end = NULL }; + CborError cborFindResult = CborNoError; + cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor); + + OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t)); + VERIFY_NON_NULL(TAG, acl, ERROR); + + // Enter ACL Map + CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 }; + cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map."); + + while (cbor_value_is_valid(&aclMap)) + { + char* tagName = NULL; + size_t len = 0; + CborType type = cbor_value_get_type(&aclMap); + if (type == CborTextStringType) + { + cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map."); + cborFindResult = cbor_value_advance(&aclMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map."); + } + if(tagName) + { + if (strcmp(tagName, OIC_JSON_ACLIST_NAME) == 0) + { + // Enter ACES Array + CborValue acesArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 }; + cborFindResult = cbor_value_enter_container(&aclMap, &acesArray); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACES Array."); + + int acesCount = 0; + while (cbor_value_is_valid(&acesArray)) + { + acesCount++; + CborValue aceMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 }; + cborFindResult = cbor_value_enter_container(&acesArray, &aceMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACE Map."); + + OicSecAce_t *ace = NULL; + ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t)); + VERIFY_NON_NULL(TAG, ace, ERROR); + LL_APPEND(acl->aces, ace); + + while (cbor_value_is_valid(&aceMap)) + { + char* name = NULL; + size_t len = 0; + CborType type = cbor_value_get_type(&aceMap); + if (type == CborTextStringType) + { + cborFindResult = cbor_value_dup_text_string(&aceMap, &name, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACE Map."); + cborFindResult = cbor_value_advance(&aceMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACE Map."); + } + if (name) + { + // Subject -- Mandatory + if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0) + { + char *subject = NULL; + cborFindResult = cbor_value_dup_text_string(&aceMap, &subject, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value."); + if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0) + { + ace->subjectuuid.id[0] = '*'; + } + else + { + OIC_LOG_V(DEBUG, TAG, "Converting subjectuuid = %s to uuid...", subject); + ret = ConvertStrToUuid(subject, &ace->subjectuuid); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + } + OICFree(subject); + } + + // Resources -- Mandatory + if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0) + { + CborValue resources = { .parser = NULL }; + cborFindResult = cbor_value_enter_container(&aceMap, &resources); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array."); + + while (cbor_value_is_valid(&resources)) + { + // rMap + CborValue rMap = { .parser = NULL }; + cborFindResult = cbor_value_enter_container(&resources, &rMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map"); + + OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t)); + VERIFY_NON_NULL(TAG, rsrc, ERROR); + LL_APPEND(ace->resources, rsrc); + + while(cbor_value_is_valid(&rMap)) + { + char *rMapName = NULL; + size_t rMapNameLen = 0; + cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag."); + cborFindResult = cbor_value_advance(&rMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value."); + + // "href" + if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName)) + { + cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value."); + } + + // "rt" + if (0 == strcmp(OIC_JSON_RT_NAME, rMapName) && cbor_value_is_array(&rMap)) + { + cbor_value_get_array_length(&rMap, &rsrc->typeLen); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length."); + VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR); + + rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*)); + VERIFY_NON_NULL(TAG, rsrc->types, ERROR); + + CborValue resourceTypes; + cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array."); + + for(size_t i = 0; cbor_value_is_valid(&resourceTypes) && cbor_value_is_text_string(&resourceTypes); i++) + { + size_t readLen = 0; + cborFindResult = cbor_value_dup_text_string(&resourceTypes, &(rsrc->types[i]), &readLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding resource type."); + cborFindResult = cbor_value_advance(&resourceTypes); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing resource type."); + } + } + + // "if" + if (0 == strcmp(OIC_JSON_IF_NAME, rMapName) && cbor_value_is_array(&rMap)) + { + cbor_value_get_array_length(&rMap, &rsrc->interfaceLen); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length."); + VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR); + + rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*)); + VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR); + + CborValue interfaces; + cborFindResult = cbor_value_enter_container(&rMap, &interfaces); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array."); + + for(size_t i = 0; cbor_value_is_valid(&interfaces) && cbor_value_is_text_string(&interfaces); i++) + { + size_t readLen = 0; + cborFindResult = cbor_value_dup_text_string(&interfaces, &(rsrc->interfaces[i]), &readLen, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF type."); + cborFindResult = cbor_value_advance(&interfaces); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing IF type."); + } + } + + // "rel" + if (0 == strcmp(OIC_JSON_REL_NAME, rMapName)) + { + cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->rel, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value."); + } + + if (cbor_value_is_valid(&rMap)) + { + cborFindResult = cbor_value_advance(&rMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map."); + } + OICFree(rMapName); + } + + if (cbor_value_is_valid(&resources)) + { + cborFindResult = cbor_value_advance(&resources); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array."); + } + } + } + + // Permissions -- Mandatory + if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0) + { + uint64_t tmp64; + cborFindResult = cbor_value_get_uint64(&aceMap, &tmp64); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value."); + ace->permission = (uint16_t)tmp64; + } + + // TODO: Need to verfication for validity + // Validity -- Not mandatory + if(strcmp(name, OIC_JSON_VALIDITY_NAME) == 0) + { + CborValue validitiesMap = {.parser = NULL}; + size_t validitySize = 0; + + cborFindResult = cbor_value_get_array_length(&aceMap, &validitySize); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Validity Array Length."); + + cborFindResult = cbor_value_enter_container(&aceMap, &validitiesMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Array Map."); + + while(cbor_value_is_valid(&validitiesMap)) + { + OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t)); + VERIFY_NON_NULL(TAG, validity, ERROR); + LL_APPEND(ace->validities, validity); + + CborValue validityMap = {.parser = NULL}; + //period (string) + cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map."); + + size_t len = 0; + cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value."); + + //recurrence (string array) + CborValue recurrenceMap = {.parser = NULL}; + cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array."); + + cborFindResult = cbor_value_get_array_length(&recurrenceMap, &validity->recurrenceLen); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array."); + + validity->recurrences = (char**)OICCalloc(validity->recurrenceLen, sizeof(char*)); + VERIFY_NON_NULL(TAG, validity->recurrences, ERROR); + + for(size_t i = 0; cbor_value_is_text_string(&recurrenceMap) && i < validity->recurrenceLen; i++) + { + cborFindResult = cbor_value_dup_text_string(&recurrenceMap, &validity->recurrences[i], &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence Value."); + + cborFindResult = cbor_value_advance(&recurrenceMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a recurrences Array."); + } + + cborFindResult = cbor_value_advance(&validitiesMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array."); + } + } + OICFree(name); + } + + if (type != CborMapType && cbor_value_is_valid(&aceMap)) + { + cborFindResult = cbor_value_advance(&aceMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array."); + } + } + + if (cbor_value_is_valid(&acesArray)) + { + cborFindResult = cbor_value_advance(&acesArray); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array."); + } + } + } + + //rownerID -- Mandatory + if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0) + { + char *stRowner = NULL; + cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value."); + OIC_LOG_V(DEBUG, TAG, "Converting rownerid = %s to uuid...", stRowner); + ret = ConvertStrToUuid(stRowner, &acl->rownerID); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + OICFree(stRowner); + } + OICFree(tagName); + } + if (cbor_value_is_valid(&aclMap)) + { + cborFindResult = cbor_value_advance(&aclMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map."); + } + } + +exit: + if (cborFindResult != CborNoError) + { + OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl"); + DeleteACLList(acl); + acl = NULL; + } + + return acl; +} + +// This function converts CBOR format to ACL data. +// Caller needs to invoke 'free' when done using // note: This function is used in unit test hence not declared static, OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size) { @@ -644,15 +988,17 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size) return NULL; } OCStackResult ret = OC_STACK_ERROR; + CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 }; CborValue aclCbor = { .parser = NULL }; CborParser parser = { .end = NULL }; CborError cborFindResult = CborNoError; + cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor); OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t)); + VERIFY_NON_NULL(TAG, acl, ERROR); // Enter ACL Map - CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 }; cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map."); @@ -677,7 +1023,6 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size) cborFindResult = cbor_value_enter_container(&aclMap, &aclistMap); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACLIST Map."); - while (cbor_value_is_valid(&aclistMap)) { char* acName = NULL; @@ -713,8 +1058,6 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size) VERIFY_NON_NULL(TAG, ace, ERROR); LL_APPEND(acl->aces, ace); - VERIFY_NON_NULL(TAG, acl, ERROR); - while (cbor_value_is_valid(&aceMap)) { char* name = NULL; @@ -786,12 +1129,31 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size) { cbor_value_get_array_length(&rMap, &rsrc->typeLen); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length."); + + CborValue resourceTypes; + + if (rsrc->typeLen == 0) + { + cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array."); + + while (!cbor_value_at_end(&resourceTypes)) + { + rsrc->typeLen++; + cborFindResult = cbor_value_advance(&resourceTypes); + if (cborFindResult != CborNoError) + { + break; + } + } + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length."); + } + VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR); rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*)); VERIFY_NON_NULL(TAG, rsrc->types, ERROR); - CborValue resourceTypes; cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array."); @@ -809,12 +1171,31 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size) { cbor_value_get_array_length(&rMap, &rsrc->interfaceLen); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length."); + + CborValue interfaces; + + if (rsrc->interfaceLen == 0) + { + cborFindResult = cbor_value_enter_container(&rMap, &interfaces); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array."); + + while (!cbor_value_at_end(&interfaces)) + { + rsrc->interfaceLen++; + cborFindResult = cbor_value_advance(&interfaces); + if (cborFindResult != CborNoError) + { + break; + } + } + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length."); + } + VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR); rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*)); VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR); - CborValue interfaces; cborFindResult = cbor_value_enter_container(&rMap, &interfaces); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array."); @@ -911,6 +1292,24 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size) VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array."); } } + +#ifdef MULTIPLE_OWNER + // eowner uuid -- Not Mandatory + if (strcmp(name, OIC_JSON_EOWNERID_NAME) == 0) + { + char *eowner = NULL; + cborFindResult = cbor_value_dup_text_string(&aceMap, &eowner, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding eownerId Value."); + if(NULL == ace->eownerID) + { + ace->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t)); + VERIFY_NON_NULL(TAG, ace->eownerID, ERROR); + } + ret = ConvertStrToUuid(eowner, ace->eownerID); + OICFree(eowner); + VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR); + } +#endif //MULTIPLE_OWNER OICFree(name); } @@ -949,6 +1348,10 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size) VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); OICFree(stRowner); } + else if (NULL != gAcl) + { + memcpy(&(acl->rownerID), &(gAcl->rownerID), sizeof(OicUuid_t)); + } OICFree(tagName); } if (cbor_value_is_valid(&aclMap)) @@ -969,6 +1372,48 @@ exit: return acl; } +#ifdef MULTIPLE_OWNER +bool IsValidAclAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, const size_t size) +{ + bool retValue = false; + OicSecAcl_t* acl = NULL; + + VERIFY_NON_NULL(TAG, uuid, ERROR); + VERIFY_NON_NULL(TAG, cborPayload, ERROR); + VERIFY_SUCCESS(TAG, 0 != size, ERROR); + + acl = CBORPayloadToAcl(cborPayload, size); + VERIFY_NON_NULL(TAG, acl, ERROR); + + OicSecAce_t* ace = NULL; + OicSecAce_t* tempAce = NULL; + LL_FOREACH_SAFE(acl->aces, ace, tempAce) + { + OicSecRsrc_t* rsrc = NULL; + OicSecRsrc_t* tempRsrc = NULL; + + VERIFY_NON_NULL(TAG, ace->eownerID, ERROR); + VERIFY_SUCCESS(TAG, memcmp(ace->eownerID->id, uuid->id, sizeof(uuid->id)) == 0, ERROR); + + LL_FOREACH_SAFE(ace->resources, rsrc, tempRsrc) + { + VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_DOXM) != 0, ERROR); + VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_CRED) != 0, ERROR); + VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_ACL) != 0, ERROR); + VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_PSTAT) != 0, ERROR); + VERIFY_SUCCESS(TAG, strcmp(rsrc->href, OIC_RSRC_TYPE_SEC_CRL) != 0, ERROR); + } + } + + retValue = true; + +exit: + DeleteACLList(acl); + + return retValue; +} +#endif //MULTIPLE_OWNER + /** * This method removes ACE for the subject and resource from the ACL * @@ -984,6 +1429,12 @@ OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource) { OIC_LOG(DEBUG, TAG, "IN RemoveACE"); + if (!gAcl) + { + OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__); + return OC_STACK_INVALID_PARAM; + } + OicSecAce_t *ace = NULL; OicSecAce_t *tempAce = NULL; bool deleteFlag = false; @@ -1296,6 +1747,26 @@ static bool IsSameValidities(OicSecValidity_t* validities1, OicSecValidity_t* va return false; } +#ifdef MULTIPLE_OWNER +static bool IsSameEowner(OicUuid_t* eowner1, OicUuid_t* eowner2) +{ + if (NULL != eowner1 && NULL != eowner2) + { + if (memcmp(eowner1->id, eowner2->id, sizeof(eowner1->id)) == 0) + { + return true; + } + } + else if (NULL == eowner1 && NULL == eowner2) + { + OIC_LOG(DEBUG, TAG, "Both eowner1 and eowner2 are NULL"); + return true; + } + + return false; +} +#endif + static bool IsSameACE(OicSecAce_t* ace1, OicSecAce_t* ace2) { if(ace1 && ace2) @@ -1320,15 +1791,100 @@ static bool IsSameACE(OicSecAce_t* ace1, OicSecAce_t* ace2) return false; } +#ifdef MULTIPLE_OWNER + if(false == IsSameEowner(ace1->eownerID, ace2->eownerID)) + { + return false; + } +#endif + return true; } return false; } +/** + * Internal function to remove all ACL data on ACL resource and persistent storage + * + * @retval + * OC_STACK_RESOURCE_DELETED - no errors + * Otherwise - error + */ +static OCStackResult RemoveAllAce(void) +{ + OCStackResult ret = OC_STACK_ERROR; + uint8_t* aclBackup = NULL; + size_t backupSize = 0; + uint8_t* payload = NULL; + size_t size = 0; + OicSecAce_t* aceItem = NULL; + OicSecAce_t* tempAce = NULL; + + OIC_LOG(INFO, TAG, "IN RemoveAllAce"); + + //Backup the current ACL + ret = AclToCBORPayload(gAcl, &aclBackup, &backupSize); + if(OC_STACK_OK == ret) + { + // Remove all ACE from ACL + LL_FOREACH_SAFE(gAcl->aces, aceItem, tempAce) + { + LL_DELETE(gAcl->aces, aceItem); + FreeACE(aceItem); + } + + //Generate empty ACL payload + ret = AclToCBORPayload(gAcl, &payload, &size); + if (OC_STACK_OK == ret ) + { + //Update the PS. + ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size); + if (OC_STACK_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "Error in UpdateSecureResourceInPS : %d", ret); + } + } + + if(OC_STACK_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "Error while DELETE ACE : %d", ret); + + //If some erorr is occured, revert back. + OicSecAcl_t* originAcl = CBORPayloadToAcl(aclBackup, backupSize); + if( originAcl ) + { + ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, aclBackup, backupSize); + if (OC_STACK_OK == ret) + { + DeleteACLList(gAcl); + gAcl = originAcl; + } + else + { + OIC_LOG_V(ERROR, TAG, "Error in UpdateSecureResourceInPS : %d", ret); + } + } + else + { + OIC_LOG(FATAL, TAG, "Error in CBORPayloadToAcl"); + ret = OC_STACK_ERROR; + } + } + } + + OICFree(aclBackup); + OICFree(payload); + + OIC_LOG(INFO, TAG, "OUT RemoveAllAce"); + + return (OC_STACK_OK == ret ? OC_STACK_RESOURCE_DELETED : ret); +} + static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest) { OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request"); + uint8_t* payload = NULL; size_t size = 0; OCEntityHandlerResult ehRet; @@ -1347,7 +1903,16 @@ static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *e const OicSecAce_t *currentAce = NULL; OicSecAcl_t targetAcl; - memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t)); + if (NULL != gAcl) + { + memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t)); + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__); + goto exit; + } + targetAcl.aces = NULL; // 'Subject' field is MUST for processing a querystring in REST request. @@ -1431,19 +1996,17 @@ static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest * if (payload) { OicSecAcl_t *newAcl = NULL; - OicSecAcl_t newAceList; OIC_LOG(DEBUG, TAG, "ACL payload from POST request << "); OIC_LOG_BUFFER(DEBUG, TAG, payload, size); newAcl = CBORPayloadToAcl(payload, size); - if (newAcl) + if (NULL != newAcl && NULL != gAcl) { bool isNewAce = true; OicSecAce_t* existAce = NULL; OicSecAce_t* newAce = NULL; OicSecAce_t* tempAce1 = NULL; OicSecAce_t* tempAce2 = NULL; - newAceList.aces = NULL; LL_FOREACH_SAFE(newAcl->aces, newAce, tempAce1) { @@ -1472,6 +2035,7 @@ static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest * } } } + memcpy(&(gAcl->rownerID), &(newAcl->rownerID), sizeof(OicUuid_t)); DeleteACLList(newAcl); @@ -1479,6 +2043,7 @@ static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest * { size_t size = 0; uint8_t *cborPayload = NULL; + if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size)) { if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK) @@ -1494,6 +2059,10 @@ static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest * } } } + else + { + OIC_LOG_V(ERROR, TAG, "%s: %s", __func__, (NULL == newAcl) ? "no new ACL" : "gAcl is NULL"); + } } //Send response to request originator @@ -1513,14 +2082,25 @@ static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest VERIFY_NON_NULL(TAG, ehRequest->query, ERROR); - // 'Subject' field is MUST for processing a querystring in REST request. - VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR); - - GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource)); + // If 'Subject' field exist, processing a querystring in REST request. + if(GetSubjectFromQueryString(ehRequest->query, &subject)) + { + GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource)); - if (OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource)) + if (OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource)) + { + ehRet = OC_EH_RESOURCE_DELETED; + } + } + // If 'subject field not exist, remove all ACL data from ACL resource + else { - ehRet = OC_EH_RESOURCE_DELETED; + OIC_LOG(WARNING, TAG, "Can not find the 'subject' in querystring, All ACL list will be removed."); + + if(OC_STACK_RESOURCE_DELETED == RemoveAllAce()) + { + ehRet = OC_EH_RESOURCE_DELETED; + } } exit: @@ -1583,7 +2163,7 @@ static OCStackResult CreateACLResource() OIC_RSRC_ACL_URI, ACLEntityHandler, NULL, - OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE); + OC_SECURE); if (OC_STACK_OK != ret) { @@ -1792,6 +2372,7 @@ OCStackResult InitACLResource() { // Read ACL resource from PS gAcl = CBORPayloadToAcl(data, size); + OICFree(data); } /* * If SVR database in persistent storage got corrupted or @@ -1838,7 +2419,7 @@ const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t ** OicSecAce_t *ace = NULL; OicSecAce_t *begin = NULL; - if (NULL == subjectId) + if (NULL == subjectId || NULL == savePtr || NULL == gAcl) { return NULL; } @@ -1882,34 +2463,223 @@ const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t ** return NULL; } -OCStackResult InstallNewACL(const uint8_t *cborPayload, const size_t size) +void printACL(const OicSecAcl_t* acl) +{ + OIC_LOG(INFO, TAG, "Print ACL:"); + + if (NULL == acl) + { + OIC_LOG(INFO, TAG, "Received NULL acl"); + return; + } + + 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 AppendACL2(const OicSecAcl_t* acl) { OCStackResult ret = OC_STACK_ERROR; + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + if (!acl) + { + OIC_LOG_V(ERROR, TAG, "%s: acl is NULL", __func__); + return OC_STACK_INVALID_PARAM; + } + + if (!gAcl) + { + OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__); + return OC_STACK_INVALID_PARAM; + } + + // 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) + { + 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; + ret = AclToCBORPayload(gAcl, &payload, &size); + if (OC_STACK_OK == ret) + { + ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size); + OICFree(payload); + } + + OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__); + + return ret; +} + +OCStackResult AppendACL(const uint8_t *cborPayload, const size_t size) +{ // Convert CBOR format to ACL data. This will also validate the ACL data received. OicSecAcl_t* newAcl = CBORPayloadToAcl(cborPayload, size); - if (newAcl) + return AppendACL2(newAcl); +} + +OCStackResult InstallACL(const OicSecAcl_t* acl) +{ + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + OCStackResult ret = OC_STACK_ERROR; + + if (!acl) + { + OIC_LOG_V(ERROR, TAG, "%s: acl is NULL", __func__); + return OC_STACK_INVALID_PARAM; + } + + if (!gAcl) + { + OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__); + return OC_STACK_INVALID_PARAM; + } + + bool isNewAce = true; + OicSecAce_t* existAce = NULL; + OicSecAce_t* newAce = NULL; + OicSecAce_t* tempAce1 = NULL; + OicSecAce_t* tempAce2 = NULL; + OicSecAcl_t* newInstallAcl = NULL; + + LL_FOREACH_SAFE(acl->aces, newAce, tempAce1) { - // Append the new ACL to existing ACL - OicSecAce_t* newAce = NULL; - LL_FOREACH(newAcl->aces, newAce) + isNewAce = true; + LL_FOREACH_SAFE(gAcl->aces, existAce, tempAce2) { - LL_APPEND(gAcl->aces, newAce); + if(IsSameACE(newAce, existAce)) + { + OIC_LOG(DEBUG, TAG, "Duplicated ACE dectected."); + ret = OC_STACK_DUPLICATE_REQUEST; + isNewAce = false; + } } - - size_t size = 0; - uint8_t *payload = NULL; - if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size)) + if(isNewAce) { - if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK) + // Append new ACE to existing ACL + OIC_LOG(DEBUG, TAG, "NEW ACE dectected."); + + OicSecAce_t* insertAce = DuplicateACE(newAce); + if(insertAce) { - ret = OC_STACK_OK; + OIC_LOG(DEBUG, TAG, "Appending new ACE.."); + + if (!newInstallAcl) + { + newInstallAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t)); + if (NULL == newInstallAcl) + { + OIC_LOG(ERROR, TAG, "Failed to acllocate ACL"); + return OC_STACK_NO_MEMORY; + } + } + LL_PREPEND(newInstallAcl->aces, insertAce); + } + else + { + OIC_LOG(ERROR, TAG, "Failed to duplicate ACE"); + DeleteACLList(newInstallAcl); + return OC_STACK_ERROR; } - OICFree(payload); } } + if (newInstallAcl) + { + ret = AppendACL2(newInstallAcl); + if (OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "Failed to append ACL"); + } + OICFree(newInstallAcl); + } + + OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__); + return ret; } @@ -2030,8 +2800,6 @@ OCStackResult UpdateDefaultSecProvACE() strlen(OIC_RSRC_DOXM_URI) + 1) == 0 || strncmp(rsrc->href, OIC_RSRC_CRED_URI, strlen(OIC_RSRC_CRED_URI) + 1) == 0 || - strncmp(rsrc->href, OIC_RSRC_ACL_URI, - strlen(OIC_RSRC_ACL_URI) + 1) == 0 || strncmp(rsrc->href, OIC_RSRC_PSTAT_URI, strlen(OIC_RSRC_PSTAT_URI) + 1) == 0) {