Add gPstat null check
[platform/upstream/iotivity.git] / resource / csdk / security / src / pstatresource.c
index e32c86c..f9834d1 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"
 
@@ -288,6 +291,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
     }
     else
     {
+        VERIFY_NON_NULL(TAG, gPstat, ERROR);
         pstat->isOp = gPstat->isOp;
         cborFindResult = CborNoError;
     }
@@ -305,6 +309,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
     }
     else
     {
+        VERIFY_NON_NULL(TAG, gPstat, ERROR);
         memcpy(&pstat->deviceID, &gPstat->deviceID, sizeof(OicUuid_t));
         cborFindResult = CborNoError;
     }
@@ -320,6 +325,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
     }
     else
     {
+        VERIFY_NON_NULL(TAG, gPstat, ERROR);
         pstat->cm = gPstat->cm;
         cborFindResult = CborNoError;
     }
@@ -335,6 +341,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
     }
     else
     {
+        VERIFY_NON_NULL(TAG, gPstat, ERROR);
         pstat->tm = gPstat->tm;
         cborFindResult = CborNoError;
     }
@@ -350,6 +357,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
     }
     else
     {
+        VERIFY_NON_NULL(TAG, gPstat, ERROR);
         pstat->om = gPstat->om;
         cborFindResult = CborNoError;
     }
@@ -533,6 +541,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 +703,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 +767,24 @@ 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.");
-                }
-             }
+                ResetSecureResourceInPS();
+                OIC_LOG(INFO, TAG, "DOXM will be reverted.");
+            }
          }
          else
          {
              OIC_LOG(ERROR, TAG, "Invalid DOXM resource.");
+             ResetSecureResourceInPS();
          }
      }
      else
@@ -907,7 +997,15 @@ exit:
  */
 bool GetPstatIsop()
 {
-    return gPstat->isOp;
+    if(NULL != gPstat)
+    {
+        return gPstat->isOp;
+    }
+    else
+    {
+        //In case of gPstat is NULL
+        return false;
+    }
 }
 
 OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid)