Add oic/sec/amacl to support SVR types
authorSachin Agrawal <sachin.agrawal@intel.com>
Fri, 26 Jun 2015 23:12:59 +0000 (16:12 -0700)
committerSachin Agrawal <sachin.agrawal@intel.com>
Tue, 14 Jul 2015 05:16:05 +0000 (05:16 +0000)
Implement oic/sec/amacl to obtain an access control
list dynamically using Access Manager Service.

Change-Id: Id4b7759e0d0821aa870d5ce9f276d9b58caccc2f
Signed-off-by: Sakthivel Samidurai <sakthivel.samidurai@intel.com>
Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1361
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Nathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Tested-by: Nathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
12 files changed:
resource/csdk/security/SConscript
resource/csdk/security/include/internal/amaclresource.h [new file with mode: 0755]
resource/csdk/security/include/internal/srmresourcestrings.h
resource/csdk/security/include/securevirtualresourcetypes.h
resource/csdk/security/include/srmutility.h
resource/csdk/security/src/amaclresource.c [new file with mode: 0644]
resource/csdk/security/src/resourcemanager.c
resource/csdk/security/src/srmresourcestrings.c
resource/csdk/security/src/srmutility.c
resource/csdk/security/unittest/oic_unittest.json
resource/csdk/stack/samples/linux/secure/oic_svr_db_client.json
resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json

index 57d39a3..f081697 100644 (file)
@@ -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 (executable)
index 0000000..e1f4f5b
--- /dev/null
@@ -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
+
+
index af37507..d579fa2 100644 (file)
@@ -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;
index 6df713b..bf687d9 100644 (file)
@@ -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;
 };
 
 /**
index d811e25..ded297d 100644 (file)
@@ -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 (file)
index 0000000..e34b6bd
--- /dev/null
@@ -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 <stdlib.h>
+#include <string.h>
+#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 <stdlib.h>
+#include <string.h>
+
+#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;
+}
index 64725cc..a75e0cf 100644 (file)
@@ -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
index 43e2c5c..4c12ad7 100644 (file)
@@ -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";
index 3f97b57..c84e130 100644 (file)
@@ -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;
+
+}
index 9ebfbdd..808e464 100644 (file)
                "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=="
+                       ]
+               }
+       ]
 }
index 17dc43f..5a2cc55 100644 (file)
@@ -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=="]
index 1f8ad5c..7346ebc 100644 (file)
@@ -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=="]