replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / src / pstatresource.c
index 3a9e291..e32c86c 100644 (file)
@@ -224,6 +224,7 @@ exit:
     {
         // reallocate and try again!
         OICFree(outPayload);
+        outPayload = NULL;
         // Since the allocated initial memory failed, double the memory.
         cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
         cborEncoderResult = CborNoError;
@@ -360,6 +361,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
 
         pstat->smLen = 1;
         pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+        VERIFY_NON_NULL(TAG, pstat->sm, ERROR);
         cborFindResult = cbor_value_get_int(&pstatMap, &sm);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM.");
         pstat->sm[0] = (OicSecDpom_t)sm;
@@ -374,6 +376,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
         VERIFY_NON_NULL(TAG, gPstat, ERROR);
         pstat->smLen = gPstat->smLen;
         pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+        VERIFY_NON_NULL(TAG, pstat->sm, ERROR);
         *pstat->sm = *gPstat->sm;
         cborFindResult = CborNoError;
     }
@@ -462,6 +465,30 @@ static bool ValidateQuery(const char * query)
     return (bInterfaceQry ? bInterfaceMatch: true);
 }
 
+#ifdef MULTIPLE_OWNER
+bool IsValidPstatAccessForSubOwner(const uint8_t *cborPayload, size_t size)
+{
+    OicSecPstat_t* pstat = NULL;
+    bool isValidPstat = true;
+
+    OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
+    VERIFY_NON_NULL(TAG, cborPayload, ERROR);
+    VERIFY_SUCCESS(TAG, 0 != size, ERROR);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToPstat(cborPayload, size, &pstat), ERROR);
+    VERIFY_NON_NULL(TAG, pstat, ERROR);
+
+    if (RESET & pstat->cm)
+    {
+        OIC_LOG(ERROR, TAG, "SubOwner can't reset the server.");
+        isValidPstat = false;
+    }
+
+exit:
+    DeletePstatBinData(pstat);
+    return isValidPstat;
+}
+#endif //MULTIPLE_OWNER
+
 /**
  * The entity handler determines how to process a GET request.
  */
@@ -517,6 +544,7 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
     OIC_LOG(INFO, TAG, "HandlePstatPostRequest  processing POST request");
     OicSecPstat_t *pstat = NULL;
     static uint16_t previousMsgId = 0;
+    bool isDuplicatedMsg = false;
 
     if (ehRequest->payload && NULL != gPstat)
     {
@@ -531,6 +559,17 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
         {
             bool validReq = false;
 
+            /*
+             * message ID is supported for CoAP over UDP only according to RFC 7252
+             * So we should check message ID to prevent duplicate request handling in case of OC_ADAPTER_IP.
+             * In case of other transport adapter, duplicate message check is not required.
+             */
+            if (OC_ADAPTER_IP == ehRequest->devAddr.adapter &&
+                 previousMsgId == ehRequest->messageID)
+            {
+                isDuplicatedMsg = true;
+            }
+
             if (true == roParsed)
             {
                     OIC_LOG(ERROR, TAG, "Not acceptable request because of read-only properties");
@@ -641,9 +680,12 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
              {
                 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
 
-                if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
-                   || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
+                if (!isDuplicatedMsg)
                 {
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+                    InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
+                                          NULL, OIC_OTM_ERROR);
+#endif
                     RestoreDoxmToInitState();
                     RestorePstatToInitState();
                     OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
@@ -659,7 +701,7 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
      {
         if(ehRequest->devAddr.adapter == OC_ADAPTER_IP)
         {
-            previousMsgId = ehRequest->messageID++;
+            previousMsgId = ehRequest->messageID;
         }
      }
 
@@ -878,3 +920,44 @@ OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid)
     }
     return retVal;
 }
+
+OCStackResult SetPstatSelfOwnership(const OicUuid_t* newROwner)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    uint8_t *cborPayload = NULL;
+    size_t size = 0;
+
+    if(NULL == gPstat)
+    {
+        ret = OC_STACK_NO_RESOURCE;
+        return ret;
+    }
+
+    if( newROwner && (false == gPstat->isOp) && (true == (TAKE_OWNER && gPstat->cm)) )
+    {
+        gPstat->cm = (OicSecDpm_t)(gPstat->cm & (~TAKE_OWNER));
+        gPstat->isOp = true;
+
+        memcpy(gPstat->deviceID.id, newROwner->id, sizeof(newROwner->id));
+        memcpy(gPstat->rownerID.id, newROwner->id, sizeof(newROwner->id));
+
+        ret = PstatToCBORPayload(gPstat, &cborPayload, &size, false);
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+        ret = UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, cborPayload, size);
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+        OICFree(cborPayload);
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "The state of PSTAT is not Ready For OTM");
+    }
+
+    return ret;
+
+exit:
+    OICFree(cborPayload);
+    return ret;
+}
+