Validate device state for RFNOP 91/208891/1
authorVitalii Irkha <v.irkha@samsung.com>
Thu, 27 Jun 2019 13:18:35 +0000 (16:18 +0300)
committerSudipto Bal <sudipto.bal@samsung.com>
Mon, 1 Jul 2019 06:41:06 +0000 (12:11 +0530)
Added more conditions before device set state to RFNOP

https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/526/commits/09d560036053995d8bd1dee875d696e8d1eb3701
(cherry picked from 09d560036053995d8bd1dee875d696e8d1eb3701)

Change-Id: I9fccbd932a1f4e56af692300e3121b39358f88c6
Signed-off-by: Vitalii Irkha <v.irkha@samsung.com>
Signed-off-by: Sudipto Bal <sudipto.bal@samsung.com>
resource/csdk/security/SConscript
resource/csdk/security/include/srmutility.h
resource/csdk/security/src/pstatresource.c
resource/csdk/security/src/srmutility.c

index 964cdd1..613faa4 100644 (file)
@@ -60,7 +60,8 @@ libocsrm_env.PrependUnique(CPPPATH = [
                '../connectivity/api',
                '../security/include',
                '../security/include/internal',
-               '../security/provisioning/include'
+               '../security/provisioning/include',
+               '#resource/csdk/security/provisioning/include/internal'
                ])
 
 if target_os not in ['arduino', 'windows']:
index 3608bbc..22936b7 100644 (file)
@@ -188,6 +188,12 @@ void SetOtmEventHandler(OicSecOtmEventHandler_t otmEventHandler);
 void InvokeOtmEventHandler(const char* addr, uint16_t port,
                            const OicUuid_t* uuid, OicSecOtmEvent_t event);
 #endif
+/**
+ * OicUuid_t to Nil UUID {.id={0000000000000000}}
+ *
+ * @return true if the OicUuid_t is the Nil UUID
+ */
+bool IsNilUuid(const OicUuid_t *uuid);
 
 #ifdef __cplusplus
 }
index 4a4c107..92e7579 100644 (file)
@@ -32,6 +32,9 @@
 #include "psinterface.h"
 #include "srmresourcestrings.h"
 #include "srmutility.h"
+#include "aclresource.h"
+#include "credresource.h"
+#include "ocprovisioningmanager.h"
 
 #define TAG  "OIC_SRM_PSTAT"
 
@@ -533,6 +536,86 @@ static OCEntityHandlerResult HandlePstatGetRequest (const OCEntityHandlerRequest
 }
 
 /**
+ * Checks if device can change state to Ready for Normal Operation.
+ */
+static OCEntityHandlerResult ValidateReadyForNOP(const OicSecPstat_t *pstat)
+{
+    OIC_LOG_V(DEBUG, TAG, "%s: IN", __func__);
+
+    const OicSecDoxm_t *doxm = GetDoxmResourceData();
+    OicUuid_t rowneruuid;
+
+    if (!doxm)
+    {
+        OIC_LOG(WARNING, TAG, "DOXM is NULL");
+        return OC_EH_NOT_ACCEPTABLE;
+    }
+
+    if (!doxm->owned)
+    {
+        OIC_LOG(WARNING, TAG, "Can't change state to Ready for Normal Operation: the device is unowned");
+        return OC_EH_NOT_ACCEPTABLE;
+    }
+
+    if (IsNilUuid(&doxm->owner))
+    {
+        OIC_LOG(WARNING, TAG, "Can't change state to Ready for Normal Operation: the device owner is NIL");
+        return OC_EH_INTERNAL_SERVER_ERROR;
+    }
+
+    if (IsNilUuid(&doxm->deviceID))
+    {
+        OIC_LOG(WARNING, TAG,
+                "Can't change state to Ready for Normal Operation: the device owner ID is NIL");
+        return OC_EH_INTERNAL_SERVER_ERROR;
+    }
+
+    if (IsNilUuid(&doxm->rownerID))
+    {
+        OIC_LOG(WARNING, TAG, "Can't change state to Ready for Normal Operation: the doxm rowner is NIL");
+        return OC_EH_INTERNAL_SERVER_ERROR;
+    }
+
+
+    if (IsNilUuid(&pstat->rownerID))
+    {
+        OIC_LOG(WARNING, TAG, "Can't change state to Ready for Normal Operation: the pstat rowner is NIL");
+        return OC_EH_INTERNAL_SERVER_ERROR;
+    }
+
+    memset(&rowneruuid, 0, sizeof(OicUuid_t));
+    if (OC_STACK_OK != GetAclRownerId(&rowneruuid))
+    {
+        OIC_LOG(WARNING, TAG, "Can't change state to Ready for Normal Operation: can't get acl");
+        return OC_EH_INTERNAL_SERVER_ERROR;
+    }
+
+    if (IsNilUuid(&rowneruuid))
+    {
+        OIC_LOG(WARNING, TAG, "Can't change state to Ready for Normal Operation: the acl rowner is NIL");
+        return OC_EH_INTERNAL_SERVER_ERROR;
+    }
+
+    memset(&rowneruuid, 0, sizeof(OicUuid_t));
+    if (OC_STACK_OK != GetCredRownerId(&rowneruuid))
+    {
+        OIC_LOG(WARNING, TAG, "Can't change state to Ready for Normal Operation: can't get cred");
+        return OC_EH_INTERNAL_SERVER_ERROR;
+    }
+
+    if (IsNilUuid(&rowneruuid))
+    {
+        OIC_LOG(WARNING, TAG, "Can't change state to Ready for Normal Operation: the cred rowner is NIL");
+        return OC_EH_INTERNAL_SERVER_ERROR;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "%s: OUT", __func__);
+
+    return OC_EH_OK;
+
+}
+
+/**
  * The entity handler determines how to process a POST request.
  * Per the REST paradigm, POST can also be used to update representation of existing
  * resource or create a new resource.
@@ -615,6 +698,11 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
                 }
                 else if (false == (pstat->cm & TAKE_OWNER) && true == pstat->isOp)
                 {
+                    ehRet = ValidateReadyForNOP(pstat);
+                    if(OC_EH_OK != ehRet)
+                    {
+                        goto exit;
+                    }
                     validReq = true;
                     OIC_LOG (INFO, TAG, "State changed to Ready for Normal Operation");
                 }
@@ -674,27 +762,25 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
            * ownership transfer related resource should be revert back to initial status.
            */
          const OicSecDoxm_t* doxm = GetDoxmResourceData();
-         if(doxm)
+         if(doxm && !doxm->owned)
          {
-             if(!doxm->owned)
-             {
-                OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
+            OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
 
-                if (!isDuplicatedMsg)
-                {
+            if (!isDuplicatedMsg)
+            {
 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
-                    InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
+                InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
                                           NULL, OIC_OTM_ERROR);
 #endif
-                    RestoreDoxmToInitState();
-                    RestorePstatToInitState();
-                    OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
-                }
-             }
+                RestoreDoxmToInitState();
+                RestorePstatToInitState();
+                OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
+            }
          }
          else
          {
              OIC_LOG(ERROR, TAG, "Invalid DOXM resource.");
+             ResetSecureResourceInPS();
          }
      }
      else
index e54095d..80b836f 100644 (file)
@@ -378,4 +378,47 @@ exit:
     }
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
+
+const OicUuid_t THE_NIL_UUID = {.id={0000000000000000}};
+
+/**
+ * Compares two OicUuid_t structs.
+ *
+ * @return true if the two OicUuid_t structs are equal, else false.
+ */
+bool UuidCmp(const OicUuid_t *firstId, const OicUuid_t *secondId)
+{
+    bool ret = false;
+    VERIFY_NON_NULL(TAG, firstId, ERROR);
+    VERIFY_NON_NULL(TAG, secondId, ERROR);
+
+    if (0 == memcmp(firstId, secondId, sizeof(OicUuid_t)))
+    {
+        ret = true;
+    }
+
+exit:
+    OIC_LOG_V(DEBUG, TAG, "%s: returning %s.", __func__, ret?"true":"false");
+    return ret;
+}
+
+/**
+ * Compares OicUuid_t to Nil UUID {.id={0000000000000000}}
+ *
+ * @return true if the OicUuid_t is the Nil UUID.
+ */
+bool IsNilUuid(const OicUuid_t *uuid)
+{
+#if !defined(NDEBUG)
+    char *strUuid = NULL;
+    ConvertUuidToStr(uuid, &strUuid);
+    if (strUuid)
+    {
+        OIC_LOG_V(DEBUG, TAG, "%s: uuid: %s.", __func__, strUuid);
+        OICFree(strUuid);
+    }
+#endif
+    return UuidCmp(uuid, &THE_NIL_UUID);
+}
+
 #endif