replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / src / aclresource.c
index 0018be0..f557a09 100644 (file)
@@ -46,8 +46,8 @@
 
 #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)
 
@@ -132,6 +132,10 @@ static void FreeACE(OicSecAce_t *ace)
         validity = NULL;
     }
 
+#ifdef MULTIPLE_OWNER
+    OICFree(ace->eownerID);
+#endif
+
     //Clean ACE
     OICFree(ace);
     ace = NULL;
@@ -252,6 +256,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;
     }
 
@@ -346,8 +362,16 @@ 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");
 
@@ -538,6 +562,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.");
     }
@@ -602,7 +642,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;
     }
@@ -614,7 +654,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;
@@ -648,6 +688,7 @@ OicSecAcl_t* CBORPayloadToAcl2(const uint8_t *cborPayload, const size_t size)
     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 };
@@ -688,8 +729,6 @@ OicSecAcl_t* CBORPayloadToAcl2(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;
@@ -948,15 +987,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.");
 
@@ -981,7 +1022,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;
@@ -1017,8 +1057,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;
@@ -1215,6 +1253,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);
                                     }
 
@@ -1277,6 +1333,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
  *
@@ -1292,6 +1390,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;
@@ -1604,6 +1708,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)
@@ -1628,6 +1752,13 @@ 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;
     }
 
@@ -1714,6 +1845,7 @@ static OCStackResult RemoveAllAce(void)
 static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
 {
     OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
+
     uint8_t* payload = NULL;
     size_t size = 0;
     OCEntityHandlerResult ehRet;
@@ -1732,7 +1864,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.
@@ -1820,7 +1961,7 @@ static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *
         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;
@@ -1879,6 +2020,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
@@ -2235,7 +2380,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;
     }
@@ -2359,12 +2504,21 @@ void printACL(const OicSecAcl_t* acl)
     }
 }
 
-OCStackResult InstallNewACL2(const OicSecAcl_t* acl)
+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;
     }
 
@@ -2395,15 +2549,99 @@ OCStackResult InstallNewACL2(const OicSecAcl_t* acl)
         OICFree(payload);
     }
 
+    OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__);
+
     return ret;
 }
 
-OCStackResult InstallNewACL(const uint8_t *cborPayload, const size_t size)
+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);
 
-    return InstallNewACL2(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)
+    {
+        isNewAce = true;
+        LL_FOREACH_SAFE(gAcl->aces, existAce, tempAce2)
+        {
+            if(IsSameACE(newAce, existAce))
+            {
+                OIC_LOG(DEBUG, TAG, "Duplicated ACE dectected.");
+                ret = OC_STACK_DUPLICATE_REQUEST;
+                isNewAce = false;
+            }
+        }
+        if(isNewAce)
+        {
+            // Append new ACE to existing ACL
+            OIC_LOG(DEBUG, TAG, "NEW ACE dectected.");
+
+            OicSecAce_t* insertAce = DuplicateACE(newAce);
+            if(insertAce)
+            {
+                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;
+            }
+        }
+    }
+
+    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;
 }
 
 /**
@@ -2523,8 +2761,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)
                     {