//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include "iotivity_config.h"
#ifdef HAVE_STRING_H
#include <string.h>
-#elif HAVE_STRINGS_H
+#elif defined(HAVE_STRINGS_H)
#include <strings.h>
#endif
#include <stdlib.h>
#include "resourcemanager.h"
#include "srmutility.h"
#include "psinterface.h"
+#include "ocpayloadcbor.h"
#include "security_internals.h"
#define NUMBER_OF_DEFAULT_SEC_RSCS 2
#define STRING_UUID_SIZE (UUID_LENGTH * 2 + 5)
-static const uint8_t ACL_MAP_SIZE = 2;
+static const uint8_t ACL_MAP_SIZE = 4;
static const uint8_t ACL_ACLIST_MAP_SIZE = 1;
static const uint8_t ACL_ACES_MAP_SIZE = 3;
-static const uint8_t ACL_RESOURCE_MAP_SIZE = 4;
+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);
{
CborEncoder rMap;
- cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, ACL_RESOURCE_MAP_SIZE);
+ size_t rsrcMapSize = ACL_RESOURCE_MAP_SIZE;
+ if(rsrc->rel)
+ {
+ rsrcMapSize++;
+ }
+
+ cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, rsrcMapSize);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
//href -- Mandatory
cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->rel, strlen(rsrc->rel));
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
}
- else
- {
- cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
- strlen(OIC_JSON_REL_NAME));
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
- cborEncoderResult = cbor_encode_text_string(&rMap, "", 0);
- VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
- }
cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
OICFree(rowner);
}
+ //RT -- Mandatory
+ CborEncoder rtArray;
+ cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_RT_NAME,
+ strlen(OIC_JSON_RT_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&aclMap, &rtArray, 1);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
+ for (size_t i = 0; i < 1; i++)
+ {
+ cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_ACL,
+ strlen(OIC_RSRC_TYPE_SEC_ACL));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&aclMap, &rtArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
+
+ //IF-- Mandatory
+ CborEncoder ifArray;
+ cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_IF_NAME,
+ strlen(OIC_JSON_IF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&aclMap, &ifArray, 1);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
+ for (size_t i = 0; i < 1; i++)
+ {
+ cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
+ strlen(OC_RSRVD_INTERFACE_DEFAULT));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&aclMap, &ifArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
+
// Close ACL Map
cborEncoderResult = cbor_encoder_close_container(&encoder, &aclMap);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACL Map.");
// 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));
+
+ // 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);
+
+ VERIFY_NON_NULL(TAG, acl, ERROR);
+
+ 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)
{
* ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
* ::OC_STACK_INVALID_PARAM on invalid parameter
*/
-static OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
+OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
{
OIC_LOG(DEBUG, TAG, "IN RemoveACE");
return false;
}
+static size_t GetNumberOfResource(OicSecRsrc_t* resources)
+{
+ size_t ret = 0;
+ if(resources)
+ {
+ OicSecRsrc_t* rsrc = NULL;
+ LL_FOREACH(resources, rsrc)
+ {
+ ret++;
+ }
+ }
+ return ret;
+}
+
+static size_t GetNumberOfValidity(OicSecValidity_t* val)
+{
+ size_t ret = 0;
+
+ if(val)
+ {
+ OicSecValidity_t* temp = NULL;
+ LL_FOREACH(val, temp)
+ {
+ ret++;
+ }
+ }
+ return ret;
+}
+
+
+static bool IsSameStringArray(char** strArr1, size_t strArr1Len,
+ char** strArr2, size_t strArr2Len)
+{
+
+ if(NULL == strArr1 && NULL == strArr2)
+ {
+ return true;
+ }
+
+ if(strArr1 && strArr2 && NULL == *strArr1 && NULL == *strArr2)
+ {
+ return true;
+ }
+
+ if(strArr1 && strArr2)
+ {
+ if(*strArr1 && *strArr2 && strArr1Len == strArr2Len)
+ {
+ size_t matchedStr = 0;
+ for(size_t i = 0; i < strArr1Len; i++)
+ {
+ for(size_t j = 0; j < strArr2Len; j++)
+ {
+ if(strcmp(strArr1[i], strArr2[j]) == 0)
+ {
+ matchedStr++;
+ }
+ }
+ }
+ if(matchedStr == strArr1Len)
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool IsSameResources(OicSecRsrc_t* resources1, OicSecRsrc_t* resources2)
+{
+ size_t numOfRsrc1 = 0;
+ size_t numOfRsrc2 = 0;
+ size_t numOfMatchedRsrc = 0;
+ OicSecRsrc_t* rsrc1 = NULL;
+ OicSecRsrc_t* rsrc2 = NULL;
+
+ if(NULL == resources1 && NULL == resources2)
+ {
+ return true;
+ }
+
+ if(resources1 && resources2)
+ {
+ numOfRsrc1 = GetNumberOfResource(resources1);
+ numOfRsrc2 = GetNumberOfResource(resources2);
+
+ if(0 == numOfRsrc1 && 0 == numOfRsrc2)
+ {
+ return true;
+ }
+
+ LL_FOREACH(resources1, rsrc1)
+ {
+ rsrc2 = NULL;
+ LL_FOREACH(resources2, rsrc2)
+ {
+ if(rsrc1 && rsrc2)
+ {
+ if(strcmp(rsrc1->href, rsrc2->href) == 0 &&
+ IsSameStringArray(rsrc1->interfaces, rsrc1->interfaceLen,
+ rsrc2->interfaces, rsrc2->interfaceLen) &&
+ IsSameStringArray(rsrc1->types, rsrc1->typeLen,
+ rsrc2->types, rsrc2->typeLen))
+ {
+ // TODO: Update codes to compare 'rel' property
+ numOfMatchedRsrc++;
+ }
+ }
+ }
+ }
+
+ if(numOfMatchedRsrc == numOfRsrc1)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool IsSameValidities(OicSecValidity_t* validities1, OicSecValidity_t* validities2)
+{
+ size_t numOfVal1 = 0;
+ size_t numOfVal2 = 0;
+ size_t numOfMatchedVal = 0;
+ OicSecValidity_t* val1 = NULL;
+ OicSecValidity_t* val2 = NULL;
+
+ if(NULL == validities1 && NULL == validities2)
+ {
+ return true;
+ }
+
+ if(validities1 && validities2)
+ {
+ numOfVal1 = GetNumberOfValidity(validities1);
+ numOfVal2 = GetNumberOfValidity(validities2);
+ if(0 == numOfVal1 && 0 == numOfVal2)
+ {
+ return true;
+ }
+
+ if(numOfVal1 == numOfVal2)
+ {
+ LL_FOREACH(validities1, val1)
+ {
+ LL_FOREACH(validities2, val2)
+ {
+ if(strcmp(val1->period, val2->period) == 0 &&
+ IsSameStringArray(val1->recurrences, val1->recurrenceLen,
+ val2->recurrences, val2->recurrenceLen))
+ {
+ numOfMatchedVal++;
+ }
+ }
+ }
+ if(numOfVal1 == numOfMatchedVal)
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool IsSameACE(OicSecAce_t* ace1, OicSecAce_t* ace2)
+{
+ if(ace1 && ace2)
+ {
+ if(memcmp(ace1->subjectuuid.id, ace2->subjectuuid.id, sizeof(ace1->subjectuuid.id)) != 0)
+ {
+ return false;
+ }
+
+ if(false == IsSameResources(ace1->resources, ace2->resources))
+ {
+ return false;
+ }
+
+ if(ace1->permission != ace2->permission)
+ {
+ return false;
+ }
+
+ if(false == IsSameValidities(ace1->validities, ace2->validities))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
{
OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
exit:
// A device should always have a default acl. Therefore, payload should never be NULL.
ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
+ OIC_LOG(DEBUG, TAG, "ACL payload with GET response");
+ OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
+
+ //Send payload to request originator
+ ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
+ OC_EH_OK : OC_EH_ERROR;
- // Send response payload to request originator
- if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
- {
- ehRet = OC_EH_ERROR;
- OIC_LOG(ERROR, TAG, "SendSRMResponse failed for HandleACLGetRequest");
- }
OICFree(payload);
OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *ehRequest)
{
OIC_LOG(INFO, TAG, "HandleACLPostRequest processing the request");
- OCEntityHandlerResult ehRet = OC_EH_ERROR;
+ OCEntityHandlerResult ehRet = OC_EH_OK;
// Convert CBOR into ACL data and update to SVR buffers. This will also validate the ACL data received.
uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
if (payload)
{
- OicSecAcl_t *newAcl = CBORPayloadToAcl(payload, size);
+ OicSecAcl_t *newAcl = NULL;
+ OIC_LOG(DEBUG, TAG, "ACL payload from POST request << ");
+ OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
+
+ newAcl = CBORPayloadToAcl(payload, size);
if (newAcl)
{
- // Append the new ACL to existing ACL
+ bool isNewAce = true;
+ OicSecAce_t* existAce = NULL;
OicSecAce_t* newAce = NULL;
- OicSecAce_t* tempAce = NULL;
- LL_FOREACH_SAFE(newAcl->aces, newAce, tempAce)
+ OicSecAce_t* tempAce1 = NULL;
+ OicSecAce_t* tempAce2 = NULL;
+
+ LL_FOREACH_SAFE(newAcl->aces, newAce, tempAce1)
{
- LL_APPEND(gAcl->aces, newAce);
+ isNewAce = true;
+ LL_FOREACH_SAFE(gAcl->aces, existAce, tempAce2)
+ {
+ if(IsSameACE(newAce, existAce))
+ {
+ isNewAce = false;
+ }
+ }
+ if(isNewAce)
+ {
+ OIC_LOG(DEBUG, TAG, "NEW ACE dectected.");
+
+ OicSecAce_t* insertAce = DuplicateACE(newAce);
+ if(insertAce)
+ {
+ OIC_LOG(DEBUG, TAG, "Appending new ACE..");
+ LL_PREPEND(gAcl->aces, insertAce);
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to duplicate ACE.");
+ ehRet = OC_EH_ERROR;
+ }
+ }
}
- newAcl->aces = NULL;
+ memcpy(&(gAcl->rownerID), &(newAcl->rownerID), sizeof(OicUuid_t));
- size_t size = 0;
- uint8_t *cborPayload = NULL;
- if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size))
+ DeleteACLList(newAcl);
+
+ if(OC_EH_OK == ehRet)
{
- if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK)
+ size_t size = 0;
+ uint8_t *cborPayload = NULL;
+
+ if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size))
{
- ehRet = OC_EH_RESOURCE_CREATED;
+ if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK)
+ {
+ ehRet = OC_EH_CHANGED;
+ }
+ OICFree(cborPayload);
+ }
+
+ if(OC_EH_CHANGED != ehRet)
+ {
+ ehRet = OC_EH_ERROR;
}
- OICFree(cborPayload);
}
}
-
- DeleteACLList(newAcl);
}
- // Send payload to request originator
- if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
- {
- ehRet = OC_EH_ERROR;
- OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleACLPostRequest");
- }
+ //Send response to request originator
+ ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
+ OC_EH_OK : OC_EH_ERROR;
OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
return ehRet;
}
exit:
- // Send payload to request originator
- if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
- {
- ehRet = OC_EH_ERROR;
- OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleACLDeleteRequest");
- }
+ //Send response to request originator
+ ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
+ OC_EH_OK : OC_EH_ERROR;
return ehRet;
}
break;
default:
- ehRet = OC_EH_ERROR;
- SendSRMResponse(ehRequest, ehRet, NULL, 0);
+ ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
+ OC_EH_OK : OC_EH_ERROR;
}
}
OIC_RSRC_ACL_URI,
ACLEntityHandler,
NULL,
- OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
+ OC_SECURE);
if (OC_STACK_OK != ret)
{
{
// Read ACL resource from PS
gAcl = CBORPayloadToAcl(data, size);
+ OICFree(data);
}
/*
* If SVR database in persistent storage got corrupted or
return NULL;
}
-OCStackResult InstallNewACL(const uint8_t *cborPayload, const size_t size)
+void printACL(const OicSecAcl_t* acl)
{
- OCStackResult ret = OC_STACK_ERROR;
+ OIC_LOG(INFO, TAG, "Print ACL:");
- // Convert CBOR format to ACL data. This will also validate the ACL data received.
- OicSecAcl_t* newAcl = CBORPayloadToAcl(cborPayload, size);
+ if (NULL == acl)
+ {
+ OIC_LOG(INFO, TAG, "Received NULL acl");
+ return;
+ }
- if (newAcl)
+ char *rowner = NULL;
+ if (OC_STACK_OK == ConvertUuidToStr(&acl->rownerID, &rowner))
{
- // Append the new ACL to existing ACL
- OicSecAce_t* newAce = NULL;
- LL_FOREACH(newAcl->aces, newAce)
+ 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
{
- LL_APPEND(gAcl->aces, newAce);
+ OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
}
+ OICFree(subjectuuid);
- size_t size = 0;
- uint8_t *payload = NULL;
- if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
+ OicSecRsrc_t *res = ace->resources;
+ int res_count = 0;
+ while (res)
{
- if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
+ 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++)
{
- ret = OC_STACK_OK;
+ OIC_LOG_V(INFO, TAG, "if[%zu] = %s", i, res->interfaces[i]);
}
- OICFree(payload);
+
+ 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;
+
+ if (!acl)
+ {
+ 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);
}
return ret;
}
+OCStackResult InstallNewACL(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);
+
+ return InstallNewACL2(newAcl);
+}
+
/**
* This function generates default ACE for security resource in case of owned status.
*