From 2eb24011347eaea1953fb820aa3d7ba57c2f6bf9 Mon Sep 17 00:00:00 2001 From: Sachin Agrawal Date: Fri, 26 Jun 2015 16:12:59 -0700 Subject: [PATCH] Add oic/sec/amacl to support SVR types Implement oic/sec/amacl to obtain an access control list dynamically using Access Manager Service. Change-Id: Id4b7759e0d0821aa870d5ce9f276d9b58caccc2f Signed-off-by: Sakthivel Samidurai Signed-off-by: Sachin Agrawal Reviewed-on: https://gerrit.iotivity.org/gerrit/1361 Tested-by: jenkins-iotivity Reviewed-by: Nathan Heldt-Sheller Tested-by: Nathan Heldt-Sheller --- resource/csdk/security/SConscript | 3 +- .../csdk/security/include/internal/amaclresource.h | 79 ++++ .../security/include/internal/srmresourcestrings.h | 6 + .../security/include/securevirtualresourcetypes.h | 3 +- resource/csdk/security/include/srmutility.h | 17 + resource/csdk/security/src/amaclresource.c | 402 +++++++++++++++++++++ resource/csdk/security/src/resourcemanager.c | 5 + resource/csdk/security/src/srmresourcestrings.c | 6 + resource/csdk/security/src/srmutility.c | 45 +++ resource/csdk/security/unittest/oic_unittest.json | 25 +- .../samples/linux/secure/oic_svr_db_client.json | 3 +- .../samples/linux/secure/oic_svr_db_server.json | 3 +- 12 files changed, 592 insertions(+), 5 deletions(-) create mode 100755 resource/csdk/security/include/internal/amaclresource.h create mode 100644 resource/csdk/security/src/amaclresource.c diff --git a/resource/csdk/security/SConscript b/resource/csdk/security/SConscript index 57d39a3..f081697 100644 --- a/resource/csdk/security/SConscript +++ b/resource/csdk/security/SConscript @@ -84,7 +84,8 @@ OCSRM_SRC = 'src/' libocsrm_src = [ OCSRM_SRC + 'secureresourcemanager.c', OCSRM_SRC + 'resourcemanager.c', - OCSRM_SRC + 'aclresource.c', + OCSRM_SRC + 'aclresource.c', + OCSRM_SRC + 'amaclresource.c', OCSRM_SRC + 'pstatresource.c', OCSRM_SRC + 'doxmresource.c', OCSRM_SRC + 'credresource.c', diff --git a/resource/csdk/security/include/internal/amaclresource.h b/resource/csdk/security/include/internal/amaclresource.h new file mode 100755 index 0000000..e1f4f5b --- /dev/null +++ b/resource/csdk/security/include/internal/amaclresource.h @@ -0,0 +1,79 @@ +//****************************************************************** +// +// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef IOTVT_SRM_AMACLR_H +#define IOTVT_SRM_AMACLR_H + +/** + * @file + * + * This file contains the APIs for the /oic/sec/amacl resource is an ACL structure that + * specifies which resources will use an Access Manager Service (AMS) to resolve access decisions. + * It dynamically obtains an ACL using an AMS. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialize Amacl resource by loading data from persistent storage. + * + * @retval OC_STACK_OK for Success, otherwise some error value + */ +OCStackResult InitAmaclResource(); + +/** + * Perform cleanup for Amacl resources. + * + * @retval none + */ +void DeInitAmaclResource(); + +/** + * This method is used by PolicyEngine to retrieve Amacl for a Subject. + * + * @param subjectId ID of the subject for which Amacl is required. + * @param savePtr is used internally by @ref GetAmaclResourceData to maintain index between + * successive calls for same subjectId. + * + * @retval reference to @ref OicSecAmacl_t if Amacl is found, else NULL + * + * @note On the first call to @ref GetAmaclResourceData, savePtr should point to NULL + */ +const OicSecAmacl_t* GetAmaclResourceData(const OicUuid_t* subjectId, OicSecAmacl_t **savePtr); + +/** + * This function converts Amacl data into JSON format. + * Caller needs to invoke 'free' when done using + * returned string. + * @param Amacl instance of OicSecAmacl_t structure. + * + * @retval pointer to Amacl in json format. + */ +char* BinToAmaclJSON(const OicSecAmacl_t * amacl); + +#ifdef __cplusplus +} +#endif + +#endif //IOTVT_SRM_AMACLR_H + + diff --git a/resource/csdk/security/include/internal/srmresourcestrings.h b/resource/csdk/security/include/internal/srmresourcestrings.h index af37507..d579fa2 100644 --- a/resource/csdk/security/include/internal/srmresourcestrings.h +++ b/resource/csdk/security/include/internal/srmresourcestrings.h @@ -32,6 +32,11 @@ extern const char * OIC_RSRC_CORE_P_URI; extern const char * OIC_RSRC_PRESENCE_URI; extern const char * OIC_RSRC_TYPES_D_URI; +//AMACL +extern const char * OIC_RSRC_TYPE_SEC_AMACL; +extern const char * OIC_RSRC_AMACL_URI; +extern const char * OIC_JSON_AMACL_NAME; + //ACL extern const char * OIC_RSRC_TYPE_SEC_ACL; extern const char * OIC_RSRC_ACL_URI; @@ -55,6 +60,7 @@ extern const char * OIC_JSON_CRED_NAME; extern const char * OIC_JSON_SUBJECT_NAME; extern const char * OIC_JSON_RESOURCES_NAME; +extern const char * OIC_JSON_AMSS_NAME; extern const char * OIC_JSON_PERMISSION_NAME; extern const char * OIC_JSON_OWNERS_NAME; extern const char * OIC_JSON_OWNER_NAME; diff --git a/resource/csdk/security/include/securevirtualresourcetypes.h b/resource/csdk/security/include/securevirtualresourcetypes.h index 6df713b..bf687d9 100644 --- a/resource/csdk/security/include/securevirtualresourcetypes.h +++ b/resource/csdk/security/include/securevirtualresourcetypes.h @@ -302,13 +302,14 @@ struct OicSecAmacl size_t resourcesLen; // the number of elts in Resources char **resources; // 0:R:M:Y:String size_t amssLen; // the number of elts in Amss - OicSecSvc_t *amss; // 1:R:M:Y:acl + OicUuid_t *amss; // 1:R:M:Y:acl size_t ownersLen; // the number of elts in Owners OicUuid_t *owners; // 2:R:M:Y:oic.uuid // NOTE: we are using UUID for Owners instead of Svc type for mid-April // SRM version only; this will change to Svc type for full implementation. //TODO change Owners type to oic.sec.svc //OicSecSvc_t *Owners; // 2:R:M:Y:oic.sec.svc + OicSecAmacl_t *next; }; /** diff --git a/resource/csdk/security/include/srmutility.h b/resource/csdk/security/include/srmutility.h index d811e25..ded297d 100644 --- a/resource/csdk/security/include/srmutility.h +++ b/resource/csdk/security/include/srmutility.h @@ -22,6 +22,8 @@ #define IOTVT_SRM_UTILITY_H #include "ocstack.h" +#include "cJSON.h" +#include "securevirtualresourcetypes.h" #ifdef __cplusplus extern "C" { @@ -97,6 +99,21 @@ void ParseQueryIterInit(unsigned char * query, OicParseQueryIter_t * parseIter); */ OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter); + + +/** + * This method acts as a helper funtion for JSON unmarshalling by various SVR's. + * + * @param jsonRoot - root JSON node containing the OicUuid array + * @param arrayItem - name of the JSON OicUuid array item + * @param numUuids - pointer to the number of OicUuid's available in JSON array + * @param uuids - pointer to the array of OicUuid's + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult AddUuidArray(cJSON* jsonRoot, const char* arrayItem, + size_t *numUuids, OicUuid_t** uuids ); + #ifdef __cplusplus } #endif // __cplusplus diff --git a/resource/csdk/security/src/amaclresource.c b/resource/csdk/security/src/amaclresource.c new file mode 100644 index 0000000..e34b6bd --- /dev/null +++ b/resource/csdk/security/src/amaclresource.c @@ -0,0 +1,402 @@ +//****************************************************************** +// +// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + +#include +#include +#include "ocstack.h" +#include "logger.h" +#include "oic_malloc.h" +#include "oic_string.h" +#include "cJSON.h" +#include "base64.h" +#include "resourcemanager.h" +#include "psinterface.h" +#include "utlist.h" +#include "srmresourcestrings.h" +#include "amaclresource.h" +#include "srmutility.h" +#include +#include + +#define TAG PCF("SRM-AMACL") + +OicSecAmacl_t *gAmacl = NULL; +static OCResourceHandle gAmaclHandle = NULL; + +void DeleteAmaclList(OicSecAmacl_t* amacl) +{ + if (amacl) + { + OicSecAmacl_t *amaclTmp1 = NULL, *amaclTmp2 = NULL; + LL_FOREACH_SAFE(amacl, amaclTmp1, amaclTmp2) + { + int i = 0; + + LL_DELETE(amacl, amaclTmp1); + + // Clean Resources + for (i = 0; i < amaclTmp1->resourcesLen; i++) + { + OICFree(amaclTmp1->resources[i]); + } + OICFree(amaclTmp1->resources); + + // Clean Amss + OICFree(amaclTmp1->amss); + + // Clean Owners + OICFree(amaclTmp1->owners); + + // Clean Amacl node itself + OICFree(amaclTmp1); + } + } +} + +/* + * This internal method converts AMACL data into JSON format. + * + * Note: Caller needs to invoke 'free' when finished using the return string. + */ +char * BinToAmaclJSON(const OicSecAmacl_t * amacl) +{ + cJSON *jsonRoot = NULL; + char *jsonStr = NULL; + + if (amacl) + { + jsonRoot = cJSON_CreateObject(); + VERIFY_NON_NULL(TAG, jsonRoot, ERROR); + + cJSON *jsonAmaclArray = NULL; + cJSON_AddItemToObject (jsonRoot, OIC_JSON_AMACL_NAME, jsonAmaclArray = cJSON_CreateArray()); + VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR); + + while(amacl) + { + char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {}; + uint32_t outLen = 0; + B64Result b64Ret = B64_OK; + + cJSON *jsonAmacl = cJSON_CreateObject(); + + // Resources -- Mandatory + cJSON *jsonRsrcArray = NULL; + cJSON_AddItemToObject(jsonAmacl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray = + cJSON_CreateArray()); + VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR); + for (int i = 0; i < amacl->resourcesLen; i++) + { + cJSON_AddItemToArray(jsonRsrcArray, cJSON_CreateString(amacl->resources[i])); + } + + // Amss -- Mandatory + cJSON *jsonAmsArray = NULL; + cJSON_AddItemToObject(jsonAmacl, OIC_JSON_AMSS_NAME, jsonAmsArray = + cJSON_CreateArray()); + VERIFY_NON_NULL(TAG, jsonAmsArray, ERROR); + for (int i = 0; i < amacl->amssLen; i++) + { + outLen = 0; + + b64Ret = b64Encode(amacl->amss[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff, + sizeof(base64Buff), &outLen); + VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); + + cJSON_AddItemToArray(jsonAmsArray, cJSON_CreateString(base64Buff)); + } + + // Owners -- Mandatory + cJSON *jsonOwnrArray = NULL; + cJSON_AddItemToObject(jsonAmacl, OIC_JSON_OWNERS_NAME, jsonOwnrArray = + cJSON_CreateArray()); + VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR); + for (int i = 0; i < amacl->ownersLen; i++) + { + outLen = 0; + + b64Ret = b64Encode(amacl->owners[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff, + sizeof(base64Buff), &outLen); + VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); + + cJSON_AddItemToArray(jsonOwnrArray, cJSON_CreateString(base64Buff)); + } + + // Attach current amacl node to Amacl Array + cJSON_AddItemToArray(jsonAmaclArray, jsonAmacl); + amacl = amacl->next; + } + + jsonStr = cJSON_PrintUnformatted(jsonRoot); + } + +exit: + if (jsonRoot) + { + cJSON_Delete(jsonRoot); + } + return jsonStr; +} + + + + +/* + * This internal method converts JSON AMACL into binary AMACL. + */ +OicSecAmacl_t * JSONToAmaclBin(const char * jsonStr) +{ + OCStackResult ret = OC_STACK_ERROR; + OicSecAmacl_t * headAmacl = NULL; + OicSecAmacl_t * prevAmacl = NULL; + cJSON *jsonRoot = NULL; + cJSON *jsonAmaclArray = NULL; + + VERIFY_NON_NULL(TAG, jsonStr, ERROR); + + jsonRoot = cJSON_Parse(jsonStr); + VERIFY_NON_NULL(TAG, jsonRoot, ERROR); + + jsonAmaclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME); + VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR); + + if (cJSON_Array == jsonAmaclArray->type) + { + int numAmacl = cJSON_GetArraySize(jsonAmaclArray); + int idx = 0; + + VERIFY_SUCCESS(TAG, numAmacl > 0, INFO); + do + { + cJSON *jsonAmacl = cJSON_GetArrayItem(jsonAmaclArray, idx); + VERIFY_NON_NULL(TAG, jsonAmacl, ERROR); + + OicSecAmacl_t *amacl = (OicSecAmacl_t*)OICCalloc(1, sizeof(OicSecAmacl_t)); + VERIFY_NON_NULL(TAG, amacl, ERROR); + + headAmacl = (headAmacl) ? headAmacl : amacl; + if (prevAmacl) + { + prevAmacl->next = amacl; + } + + size_t jsonObjLen = 0; + cJSON *jsonObj = NULL; + + // Resources -- Mandatory + jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME); + VERIFY_NON_NULL(TAG, jsonObj, ERROR); + VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR); + + amacl->resourcesLen = cJSON_GetArraySize(jsonObj); + VERIFY_SUCCESS(TAG, amacl->resourcesLen > 0, ERROR); + amacl->resources = (char**)OICCalloc(amacl->resourcesLen, sizeof(char*)); + VERIFY_NON_NULL(TAG, (amacl->resources), ERROR); + + int idxx = 0; + do + { + cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx); + VERIFY_NON_NULL(TAG, jsonRsrc, ERROR); + + jsonObjLen = strlen(jsonRsrc->valuestring) + 1; + amacl->resources[idxx] = (char*)OICMalloc(jsonObjLen); + VERIFY_NON_NULL(TAG, (amacl->resources[idxx]), ERROR); + OICStrcpy(amacl->resources[idxx], jsonObjLen, jsonRsrc->valuestring); + } while ( ++idxx < amacl->resourcesLen); + + // Amss -- Mandatory + VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_AMSS_NAME, + &(amacl->amssLen), &(amacl->amss)), ERROR); + + // Owners -- Mandatory + VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_OWNERS_NAME, + &(amacl->ownersLen), &(amacl->owners)), ERROR); + + prevAmacl = amacl; + } while( ++idx < numAmacl); + } + + ret = OC_STACK_OK; + +exit: + cJSON_Delete(jsonRoot); + if (OC_STACK_OK != ret) + { + DeleteAmaclList(headAmacl); + headAmacl = NULL; + } + return headAmacl; +} + +static OCEntityHandlerResult HandleAmaclGetRequest (const OCEntityHandlerRequest * ehRequest) +{ + // Convert Amacl data into JSON for transmission + char* jsonStr = BinToAmaclJSON(gAmacl); + + OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR); + + // Send response payload to request originator + SendSRMResponse(ehRequest, ehRet, jsonStr); + + OICFree(jsonStr); + + OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet); + return ehRet; +} + +static OCEntityHandlerResult HandleAmaclPostRequest (const OCEntityHandlerRequest * ehRequest) +{ + OCEntityHandlerResult ehRet = OC_EH_ERROR; + + // Convert JSON Amacl data into binary. This will also validate the Amacl data received. + OicSecAmacl_t* newAmacl = JSONToAmaclBin((char *)(ehRequest->reqJSONPayload)); + + if (newAmacl) + { + // Append the new Amacl to existing Amacl + LL_APPEND(gAmacl, newAmacl); + + // Convert Amacl data into JSON for update to persistent storage + char *jsonStr = BinToAmaclJSON(gAmacl); + if (jsonStr) + { + cJSON *jsonAmacl = cJSON_Parse(jsonStr); + OICFree(jsonStr); + + if ((jsonAmacl) && + (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_AMACL_NAME, jsonAmacl))) + { + ehRet = OC_EH_RESOURCE_CREATED; + } + cJSON_Delete(jsonAmacl); + } + } + + // Send payload to request originator + SendSRMResponse(ehRequest, ehRet, NULL); + + OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet); + return ehRet; +} + +/* + * This internal method is the entity handler for Amacl resources and + * will handle REST request (GET/PUT/POST/DEL) for them. + */ +OCEntityHandlerResult AmaclEntityHandler (OCEntityHandlerFlag flag, + OCEntityHandlerRequest * ehRequest, + void* callbackParameter) +{ + OCEntityHandlerResult ehRet = OC_EH_ERROR; + + if (!ehRequest) + { + return ehRet; + } + + if (flag & OC_REQUEST_FLAG) + { + OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG")); + switch (ehRequest->method) + { + case OC_REST_GET: + ehRet = HandleAmaclGetRequest(ehRequest); + break; + + case OC_REST_POST: + ehRet = HandleAmaclPostRequest(ehRequest); + break; + + default: + ehRet = OC_EH_ERROR; + SendSRMResponse(ehRequest, ehRet, NULL); + } + } + + return ehRet; +} + +/* + * This internal method is used to create '/oic/sec/amacl' resource. + */ +OCStackResult CreateAmaclResource() +{ + OCStackResult ret; + + ret = OCCreateResource(&gAmaclHandle, + OIC_RSRC_TYPE_SEC_AMACL, + OIC_MI_DEF, + OIC_RSRC_AMACL_URI, + AmaclEntityHandler, + NULL, + OC_OBSERVABLE); + + if (OC_STACK_OK != ret) + { + OC_LOG (FATAL, TAG, PCF("Unable to instantiate Amacl resource")); + DeInitAmaclResource(); + } + return ret; +} + +/** + * Initialize Amacl resource by loading data from persistent storage. + * + * @retval OC_STACK_OK for Success, otherwise some error value + */ +OCStackResult InitAmaclResource() +{ + OCStackResult ret = OC_STACK_ERROR; + + // Read Amacl resource from PS + char* jsonSVRDatabase = GetSVRDatabase(); + + if (jsonSVRDatabase) + { + // Convert JSON Amacl into binary format + gAmacl = JSONToAmaclBin(jsonSVRDatabase); + OICFree(jsonSVRDatabase); + } + + // Instantiate 'oic/sec/amacl' resource + ret = CreateAmaclResource(); + + if (OC_STACK_OK != ret) + { + DeInitAmaclResource(); + } + return ret; +} + +/** + * Perform cleanup for Amacl resources. + * + * @retval none + */ +void DeInitAmaclResource() +{ + OCDeleteResource(gAmaclHandle); + gAmaclHandle = NULL; + + DeleteAmaclList(gAmacl); + gAmacl = NULL; +} diff --git a/resource/csdk/security/src/resourcemanager.c b/resource/csdk/security/src/resourcemanager.c index 64725cc..a75e0cf 100644 --- a/resource/csdk/security/src/resourcemanager.c +++ b/resource/csdk/security/src/resourcemanager.c @@ -24,6 +24,7 @@ #include "pstatresource.h" #include "doxmresource.h" #include "credresource.h" +#include "amaclresource.h" #include "oic_malloc.h" #include "logger.h" #include "utlist.h" @@ -87,6 +88,10 @@ OCStackResult InitSecureResources( ) { ret = InitCredResource(); } + if(OC_STACK_OK == ret) + { + ret = InitAmaclResource(); + } if(OC_STACK_OK != ret) { //TODO: Update the default behavior if one of the SVR fails diff --git a/resource/csdk/security/src/srmresourcestrings.c b/resource/csdk/security/src/srmresourcestrings.c index 43e2c5c..4c12ad7 100644 --- a/resource/csdk/security/src/srmresourcestrings.c +++ b/resource/csdk/security/src/srmresourcestrings.c @@ -30,6 +30,11 @@ const char * OIC_RSRC_CORE_P_URI = "/oic/p"; const char * OIC_RSRC_PRESENCE_URI = "/oic/ad"; const char * OIC_RSRC_TYPES_D_URI = "/oic/res/types/d"; +//AMACL +const char * OIC_RSRC_TYPE_SEC_AMACL = "oic.sec.amacl"; +const char * OIC_RSRC_AMACL_URI = "/oic/sec/amacl"; +const char * OIC_JSON_AMACL_NAME = "amacl"; + //ACL const char * OIC_RSRC_TYPE_SEC_ACL = "oic.sec.acl"; const char * OIC_RSRC_ACL_URI = "/oic/sec/acl"; @@ -52,6 +57,7 @@ const char * OIC_JSON_CRED_NAME = "cred"; const char * OIC_JSON_SUBJECT_NAME = "sub"; const char * OIC_JSON_RESOURCES_NAME = "rsrc"; +const char * OIC_JSON_AMSS_NAME = "amss"; const char * OIC_JSON_PERMISSION_NAME = "perms"; const char * OIC_JSON_OWNERS_NAME = "ownrs"; const char * OIC_JSON_OWNER_NAME = "ownr"; diff --git a/resource/csdk/security/src/srmutility.c b/resource/csdk/security/src/srmutility.c index 3f97b57..c84e130 100644 --- a/resource/csdk/security/src/srmutility.c +++ b/resource/csdk/security/src/srmutility.c @@ -23,6 +23,8 @@ #include "srmutility.h" #include "srmresourcestrings.h" #include "logger.h" +#include "oic_malloc.h" +#include "base64.h" #define TAG PCF("SRM-UTILITY") @@ -84,3 +86,46 @@ OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter) } return NULL; } + + +// TODO This functionality is replicated in all SVR's and therefore we need +// to encapsulate it in a common method. However, this may not be the right +// file for this method. +OCStackResult AddUuidArray(cJSON* jsonRoot, const char* arrayItem, + size_t *numUuids, OicUuid_t** uuids ) +{ + int idxx = 0; + cJSON* jsonObj = cJSON_GetObjectItem(jsonRoot, arrayItem); + VERIFY_NON_NULL(TAG, jsonObj, ERROR); + VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR); + + *numUuids = cJSON_GetArraySize(jsonObj); + VERIFY_SUCCESS(TAG, *numUuids > 0, ERROR); + *uuids = (OicUuid_t*)OICCalloc(*numUuids, sizeof(OicUuid_t)); + VERIFY_NON_NULL(TAG, *uuids, ERROR); + + do + { + unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {}; + uint32_t outLen = 0; + B64Result b64Ret = B64_OK; + + cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx); + VERIFY_NON_NULL(TAG, jsonOwnr, ERROR); + VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR); + + outLen = 0; + b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff, + sizeof(base64Buff), &outLen); + + VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof((*uuids)[idxx].id)), + ERROR); + memcpy((*uuids)[idxx].id, base64Buff, outLen); + } while ( ++idxx < *numUuids); + + return OC_STACK_OK; + +exit: + return OC_STACK_ERROR; + +} diff --git a/resource/csdk/security/unittest/oic_unittest.json b/resource/csdk/security/unittest/oic_unittest.json index 9ebfbdd..808e464 100644 --- a/resource/csdk/security/unittest/oic_unittest.json +++ b/resource/csdk/security/unittest/oic_unittest.json @@ -33,5 +33,28 @@ "tm": 48, "om": 0, "sm": [3, 1] - } + }, + + "amacl": [ + { + "rsrc": ["/a/led", "/a/fan"], + "amss": [ + "NTU1NTU1NTU1NTU1NTU1NQ==", + "NjY2NjY2NjY2NjY2NjY2Ng==" + ], + "ownrs" : [ + "MjIyMjIyMjIyMjIyMjIyMg==" + ] + }, + { + "rsrc": ["/b/led", "/b/fan"], + "amss": [ + "NTU1NTU1NTU1NTU1NTU1NQ==", + "NjY2NjY2NjY2NjY2NjY2Ng==" + ], + "ownrs" : [ + "MjIyMjIyMjIyMjIyMjIyMg==" + ] + } + ] } diff --git a/resource/csdk/stack/samples/linux/secure/oic_svr_db_client.json b/resource/csdk/stack/samples/linux/secure/oic_svr_db_client.json index 17dc43f..5a2cc55 100644 --- a/resource/csdk/stack/samples/linux/secure/oic_svr_db_client.json +++ b/resource/csdk/stack/samples/linux/secure/oic_svr_db_client.json @@ -8,7 +8,8 @@ "/oic/p", "/oic/res/types/d", "/oic/ad", - "/oic/sec/acl" + "/oic/sec/acl", + "/oic/sec/amacl" ], "perms": 2, "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] diff --git a/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json b/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json index 1f8ad5c..7346ebc 100644 --- a/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json +++ b/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json @@ -8,7 +8,8 @@ "/oic/p", "/oic/res/types/d", "/oic/ad", - "/oic/sec/acl" + "/oic/sec/acl", + "/oic/sec/amacl" ], "perms": 2, "ownrs" : ["MTExMTExMTExMTExMTExMQ=="] -- 2.7.4