#include "pinoxmcommon.h"
#include "oxmverifycommon.h"
#include "octhread.h"
+#include "oic_time.h"
+#include "oic_string.h"
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
#include "pkix_interface.h"
static oc_mutex g_mutexDoxm = NULL;
static bool g_isDoxmNull = false;
static OCResourceHandle gDoxmHandle = NULL;
+static oc_mutex g_mutexWait;
+static oc_thread g_waitConfirmThreadId;
+oc_cond g_condWait;
static InformOxmSelectedCallback_t g_InformOxmSelectedCallback = NULL;
+static bool g_isConfirmResult;
static OicSecOxm_t gOicSecDoxmJustWorks = OIC_JUST_WORKS;
static OicSecDoxm_t gDefaultDoxm =
OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
}
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRequest);
+
+static void DestroyEntityHandlerRequest(OCEntityHandlerRequest * ehRequest)
+{
+ if (ehRequest == NULL) {
+ OIC_LOG(WARNING, TAG, "ehRequest is NULL");
+ return;
+ }
+
+ OICFree(ehRequest->query);
+
+ if (ehRequest->payload) {
+ OICFree(((OCSecurityPayload *)ehRequest->payload)->securityData);
+ OICFree(ehRequest->payload);
+ }
+
+ OICFree(ehRequest);
+}
+
+void * WaitConfirm(OCEntityHandlerRequest * ehRequest)
+{
+ bool confirmResult = false, confirmState = false;
+
+ oc_mutex_lock(g_mutexWait);
+ oc_cond_wait(g_condWait, g_mutexWait);
+ oc_cond_free(g_condWait);
+ g_condWait = NULL;
+
+ oc_mutex_unlock(g_mutexWait);
+ oc_mutex_free(g_mutexWait);
+ g_mutexWait = NULL;
+
+ g_isConfirmResult = true;
+ GetAsyncVerifyUserResult(&confirmResult, &confirmState);
+ if (confirmResult == true)
+ {
+ gConfirmState = CONFIRM_STATE_ACCEPTED;
+ HandleDoxmPostRequest(ehRequest);
+ g_isConfirmResult = false;
+ }
+ else
+ {
+ gConfirmState = CONFIRM_STATE_DENIED;
+ HandleDoxmPostRequest(ehRequest);
+ g_isConfirmResult = false;
+ }
+
+ DestroyEntityHandlerRequest(ehRequest);
+
+ return NULL;
+}
+
+static OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest)
+{
+ OIC_LOG(INFO, TAG, "Copying received request for slow response");
+
+ if (!entityHandlerRequest)
+ {
+ OIC_LOG_V(ERROR, TAG, "%s: entityHandlerRequest is NULL", __func__);
+ return NULL;
+ }
+
+ OCEntityHandlerRequest *copyOfRequest =
+ (OCEntityHandlerRequest *)OICCalloc(1, sizeof(OCEntityHandlerRequest));
+ if(!copyOfRequest)
+ {
+ OIC_LOG(ERROR, TAG, "Copy failed due to allocation failure");
+ return NULL;
+ }
+
+ memcpy(copyOfRequest, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
+
+ if (entityHandlerRequest->query)
+ {
+ copyOfRequest->query = OICStrdup(entityHandlerRequest->query);
+ if(!copyOfRequest->query)
+ {
+ OIC_LOG(ERROR, TAG, "Copy failed due to allocation failure");
+ OICFree(copyOfRequest);
+ return NULL;
+ }
+ }
+
+ if (entityHandlerRequest->payload)
+ {
+ copyOfRequest->payload =
+ (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
+ if(!copyOfRequest->payload)
+ {
+ OIC_LOG(ERROR, TAG, "Copy failed due to allocation failure");
+ OICFree(copyOfRequest->query);
+ OICFree(copyOfRequest);
+ return NULL;
+ }
+
+ if (((OCSecurityPayload *)entityHandlerRequest->payload)->payloadSize)
+ {
+ ((OCSecurityPayload *)copyOfRequest->payload)->securityData =
+ (uint8_t *)OICCalloc(1, ((OCSecurityPayload *)entityHandlerRequest->payload)->payloadSize);
+ if(!((OCSecurityPayload *)copyOfRequest->payload)->securityData)
+ {
+ OIC_LOG(ERROR, TAG, "Copy failed due to allocation failure");
+ OICFree(copyOfRequest->payload);
+ OICFree(copyOfRequest->query);
+ OICFree(copyOfRequest);
+ return NULL;
+ }
+
+ memcpy(((OCSecurityPayload *)copyOfRequest->payload)->securityData,
+ ((OCSecurityPayload *)entityHandlerRequest->payload)->securityData,
+ ((OCSecurityPayload *)entityHandlerRequest->payload)->payloadSize);
+
+ ((OCSecurityPayload *)(copyOfRequest->payload))->payloadSize =
+ ((OCSecurityPayload *)(entityHandlerRequest->payload))->payloadSize;
+ }
+
+ copyOfRequest->payload->type = entityHandlerRequest->payload->type;
+ copyOfRequest->messageID = entityHandlerRequest->messageID;
+ }
+
+ // Ignore vendor specific header options for example
+ copyOfRequest->numRcvdVendorSpecificHeaderOptions = 0;
+ copyOfRequest->rcvdVendorSpecificHeaderOptions = NULL;
+
+ OIC_LOG(INFO, TAG, "Copied client request");
+
+ return copyOfRequest;
+}
+#endif // defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+
static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRequest)
{
OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing POST request");
* In case of other transport adapter, duplicate message check is not required.
*/
if (OC_ADAPTER_IP == ehRequest->devAddr.adapter &&
- previousMsgId == ehRequest->messageID)
+ previousMsgId == ehRequest->messageID && g_isConfirmResult == false)
{
isDuplicatedMsg = true;
}
ehRet = OC_EH_NOT_ACCEPTABLE;
goto exit;
}
+
+ if(0 != memcmp(&gDoxm->owner.id, &newDoxm->owner.id, sizeof(gDoxm->owner.id)))
+ {
+ OIC_LOG(ERROR, TAG, "Not acceptable request for owned property");
+ ehRet = OC_EH_NOT_ACCEPTABLE;
+ }
+
//Update gDoxm based on newDoxm
updateWriteableProperty(newDoxm, gDoxm);
#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
else if (OIC_MANUFACTURER_CERTIFICATE == newDoxm->oxmSel || OIC_CON_MFG_CERT == newDoxm->oxmSel)
{
- //Get user confirmation
- if (false == newDoxm->owned &&
- false == isDuplicatedMsg &&
- memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
+ if (CONFIRM_STATE_ACCEPTED != gConfirmState && CONFIRM_STATE_DENIED != gConfirmState)
{
- gConfirmMsgId = ehRequest->messageID;
- gConfirmState = CONFIRM_STATE_WAIT;
- if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, USER_CONFIRM))
- {
- ehRet = OC_EH_NOT_ACCEPTABLE;
- gConfirmState = CONFIRM_STATE_DENIED;
- goto exit;
- }
- else
+ //Get user confirmation
+ if (false == newDoxm->owned &&
+ false == isDuplicatedMsg &&
+ memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
{
- ehRet = OC_EH_OK;
- gConfirmState = CONFIRM_STATE_ACCEPTED;
+ gConfirmMsgId = ehRequest->messageID;
+ gConfirmState = CONFIRM_STATE_WAIT;
+
+ if (OC_STACK_OK != VerifyUserConfirm())
+ {
+ if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, USER_CONFIRM))
+ {
+ ehRet = OC_EH_NOT_ACCEPTABLE;
+ gConfirmState = CONFIRM_STATE_DENIED;
+ goto exit;
+ }
+ }
+ else
+ {
+ OCEntityHandlerRequest * ehRequestCopy = CopyRequest(ehRequest);
+ VERIFY_NON_NULL(TAG, ehRequestCopy, ERROR);
+
+ g_condWait = oc_cond_new();
+ g_mutexWait = oc_mutex_new();
+ if (oc_thread_new (&g_waitConfirmThreadId, WaitConfirm, ehRequestCopy))
+ {
+ oc_thread_detach(g_waitConfirmThreadId);
+ }
+
+ previousMsgId = ehRequest->messageID;
+
+ return OC_EH_SLOW;
+ }
}
}
+ else if (CONFIRM_STATE_DENIED == gConfirmState)
+ {
+ ehRet = OC_EH_NOT_ACCEPTABLE;
+ goto exit;
+ }
//Save the owner's UUID to derive owner credential
memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
NULL, OIC_OTM_ERROR);
#endif
- RestoreDoxmToInitState();
- RestorePstatToInitState();
+ ResetSecureResourceInPS();
OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
}
}