X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fsecurity%2Fsrc%2Fpolicyengine.c;h=779688c4deb4e2b4e43a004c323dd0df62d12a24;hb=841c433b9e28239bd8e29e46f23d1269514f619e;hp=00fe55b9e7334950af2fed65f021e05169b50788;hpb=155e3a129b0d95d0179cc60f7c254910c0f0aa8e;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/security/src/policyengine.c b/resource/csdk/security/src/policyengine.c index 00fe55b..779688c 100644 --- a/resource/csdk/security/src/policyengine.c +++ b/resource/csdk/security/src/policyengine.c @@ -17,9 +17,12 @@ // limitations under the License. // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#include +#include "utlist.h" #include "oic_malloc.h" #include "policyengine.h" +#include "amsmgr.h" #include "resourcemanager.h" #include "securevirtualresourcetypes.h" #include "srmresourcestrings.h" @@ -28,25 +31,31 @@ #include "srmutility.h" #include "doxmresource.h" #include "iotvticalendar.h" -#include +#include "pstatresource.h" +#include "dpairingresource.h" +#include "pconfresource.h" +#include "amaclresource.h" +#include "credresource.h" -#define TAG "SRM-PE" +#define TAG "OIC_SRM_PE" -/** - * Return the uint16_t CRUDN permission corresponding to passed CAMethod_t. - */ uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method) { uint16_t perm = 0; - switch(method) + switch (method) { case CA_GET: perm = (uint16_t)PERMISSION_READ; break; - case CA_POST: // For now we treat all PUT & POST as Write - case CA_PUT: // because we don't know if resource exists yet. + case CA_POST: // Treat all POST as Write (Update) because + // we don't know if resource exists yet. + // This will be addressed in IoTivity impl of OCF 1.0 perm = (uint16_t)PERMISSION_WRITE; break; + case CA_PUT: // Per convention, OIC/OCF uses PUT only for Create, + // never for Update. + perm = (uint16_t)PERMISSION_CREATE; + break; case CA_DELETE: perm = (uint16_t)PERMISSION_DELETE; break; @@ -58,16 +67,22 @@ uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method) } /** - * @brief Compares two OicUuid_t structs. + * Compares two OicUuid_t structs. + * * @return true if the two OicUuid_t structs are equal, else false. */ -bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId) +static bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId) { // TODO use VERIFY macros to check for null when they are merged. if(NULL == firstId || NULL == secondId) { return false; } + // Check empty uuid string + if('\0' == firstId->id[0] || '\0' == secondId->id[0]) + { + return false; + } for(int i = 0; i < UUID_LENGTH; i++) { if(firstId->id[i] != secondId->id[i]) @@ -78,53 +93,256 @@ bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId) return true; } - -/** - * Set the state and clear other stateful context vars. - */ void SetPolicyEngineState(PEContext_t *context, const PEState_t state) { + if (NULL == context) + { + return; + } + // Clear stateful context variables. - OICFree(context->subject); - context->subject = NULL; - OICFree(context->resource); - context->resource = NULL; + memset(&context->subject, 0, sizeof(context->subject)); + memset(&context->resource, 0, sizeof(context->resource)); context->permission = 0x0; - context->matchingAclFound = false; + context->amsProcessing = false; context->retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR; + if (context->amsMgrContext) + { + if (context->amsMgrContext->requestInfo) + { + FreeCARequestInfo(context->amsMgrContext->requestInfo); + } + OICFree(context->amsMgrContext->endpoint); + memset(context->amsMgrContext, 0, sizeof(AmsMgrContext_t)); + } + // Set state. context->state = state; } /** - * @brief Compare the request's subject to DevOwner. + * Compare the request's subject to DevOwner. + * + * @return true if context->subjectId == GetDoxmDevOwner(), else false. + */ +static bool IsRequestFromDevOwner(PEContext_t *context) +{ + bool retVal = false; + + if(NULL == context) + { + return retVal; + } + + /* + if(OC_STACK_OK == GetDoxmDevOwnerId(&ownerid)) + { + retVal = UuidCmp(&context->subject, &ownerid); + } + */ + + // TODO: Added as workaround for CTT + OicSecDoxm_t* doxm = (OicSecDoxm_t*) GetDoxmResourceData(); + if (doxm) + { + retVal = UuidCmp(&doxm->owner, &context->subject); + } + return retVal; +} + + +#ifdef MULTIPLE_OWNER +/** + * Compare the request's subject to SubOwner. * - * @return true if context->subjectId == GetDoxmDevOwner(), else false + * @return true if context->subjectId exist subowner list, else false. */ -bool IsRequestFromDevOwner(PEContext_t *context) +static bool IsRequestFromSubOwner(PEContext_t *context) { bool retVal = false; - OicUuid_t owner; - if(OC_STACK_OK == GetDoxmDevOwnerId(&owner)) + if(NULL == context) { - retVal = UuidCmp(context->subject, &owner); + return retVal; + } + + if(IsSubOwner(&context->subject)) + { + retVal = true; + } + + if(true == retVal) + { + OIC_LOG(INFO, TAG, "PE.IsRequestFromSubOwner(): returning true"); + } + else + { + OIC_LOG(INFO, TAG, "PE.IsRequestFromSubOwner(): returning false"); } return retVal; } + +/** + * Verify the SubOwner's request. + * + * @return true if request is valid, else false. + */ +static bool IsValidRequestFromSubOwner(PEContext_t *context) +{ + bool isValidRequest = false; + + if(NULL == context) + { + return isValidRequest; + } + + switch(context->resourceType) + { + case OIC_R_DOXM_TYPE: + //SubOwner has READ permission only for DOXM + if(PERMISSION_READ == context->permission) + { + isValidRequest = true; + } + break; + case OIC_R_PSTAT_TYPE: + //SubOwner has full permsion for PSTAT + isValidRequest = true; + break; + case OIC_R_CRED_TYPE: + //SubOwner can only access the credential which is registered as the eowner. + isValidRequest = IsValidCredentialAccessForSubOwner(&context->subject, context->payload, context->payloadSize); + break; + case OIC_R_ACL_TYPE: + //SubOwner can only access the ACL which is registered as the eowner. + isValidRequest = IsValidAclAccessForSubOwner(&context->subject, context->payload, context->payloadSize); + break; + default: + //SubOwner has full permission for all resource except the security resource + isValidRequest = true; + break; + } + + if(isValidRequest) + { + OIC_LOG(INFO, TAG, "PE.IsValidRequestFromSubOwner(): returning true"); + } + else + { + OIC_LOG(INFO, TAG, "PE.IsValidRequestFromSubOwner(): returning false"); + } + + return isValidRequest; +} +#endif //MULTIPLE_OWNER + + +// TODO - remove these function placeholders as they are implemented +// in the resource entity handler code. +// Note that because many SVRs do not have a rowner, in those cases we +// just return "OC_STACK_ERROR" which results in a "false" return by +// IsRequestFromResourceOwner(). +// As these SVRs are revised to have a rowner, these functions should be +// replaced (see pstatresource.c for example of GetPstatRownerId). + +OCStackResult GetCrlRownerId(OicUuid_t *rowner) +{ + OC_UNUSED(rowner); + rowner = NULL; + return OC_STACK_ERROR; +} + +OCStackResult GetSaclRownerId(OicUuid_t *rowner) +{ + OC_UNUSED(rowner); + rowner = NULL; + return OC_STACK_ERROR; +} + +OCStackResult GetSvcRownerId(OicUuid_t *rowner) +{ + OC_UNUSED(rowner); + rowner = NULL; + return OC_STACK_ERROR; +} + +static GetSvrRownerId_t GetSvrRownerId[OIC_SEC_SVR_TYPE_COUNT] = { + GetAclRownerId, + GetAmaclRownerId, + GetCredRownerId, + GetCrlRownerId, + GetDoxmRownerId, + GetDpairingRownerId, + GetPconfRownerId, + GetPstatRownerId, + GetSaclRownerId, + GetSvcRownerId +}; + +/** + * Compare the request's subject to resource.ROwner. + * + * @return true if context->subjectId equals SVR rowner id, else return false + */ +bool IsRequestFromResourceOwner(PEContext_t *context) +{ + bool retVal = false; + OicUuid_t resourceOwner; + + if(NULL == context) + { + return false; + } + + if((OIC_R_ACL_TYPE <= context->resourceType) && \ + (OIC_SEC_SVR_TYPE_COUNT > context->resourceType)) + { + if(OC_STACK_OK == GetSvrRownerId[(int)context->resourceType](&resourceOwner)) + { + retVal = UuidCmp(&context->subject, &resourceOwner); + } + } + + if(true == retVal) + { + OIC_LOG(INFO, TAG, "PE.IsRequestFromResourceOwner(): returning true"); + } + else + { + OIC_LOG(INFO, TAG, "PE.IsRequestFromResourceOwner(): returning false"); + } + + return retVal; +} + +INLINE_API bool IsRequestSubjectEmpty(PEContext_t *context) +{ + OicUuid_t emptySubject = {.id={0}}; + + if(NULL == context) + { + return false; + } + + return (memcmp(&context->subject, &emptySubject, sizeof(OicUuid_t)) == 0) ? + true : false; +} + /** * Bitwise check to see if 'permission' contains 'request'. - * @param permission The allowed CRUDN permission. - * @param request The CRUDN permission being requested. + * + * @param permission is the allowed CRUDN permission. + * @param request is the CRUDN permission being requested. + * * @return true if 'permission' bits include all 'request' bits. */ -static inline bool IsPermissionAllowingRequest(const uint16_t permission, +INLINE_API bool IsPermissionAllowingRequest(const uint16_t permission, const uint16_t request) { - if(request == (request & permission)) + if (request == (request & permission)) { return true; } @@ -136,10 +354,16 @@ static inline bool IsPermissionAllowingRequest(const uint16_t permission, /** * Compare the passed subject to the wildcard (aka anonymous) subjectId. + * * @return true if 'subject' is the wildcard, false if it is not. */ -static inline bool IsWildCardSubject(OicUuid_t *subject) +INLINE_API bool IsWildCardSubject(OicUuid_t *subject) { + if(NULL == subject) + { + return false; + } + // Because always comparing to string literal, use strcmp() if(0 == memcmp(subject, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t))) { @@ -154,65 +378,67 @@ static inline bool IsWildCardSubject(OicUuid_t *subject) /** * Copy the subject, resource and permission into the context fields. */ -void CopyParamsToContext( - PEContext_t *context, - const OicUuid_t *subjectId, - const char *resource, - const uint16_t requestedPermission) +static void CopyParamsToContext(PEContext_t *context, + const OicUuid_t *subjectId, + const char *resource, + const uint16_t requestedPermission) { size_t length = 0; - // Free any existing subject. - OICFree(context->subject); - // Copy the subjectId into context. - context->subject = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t)); - VERIFY_NON_NULL(TAG, context->subject, ERROR); - memcpy(context->subject, subjectId, sizeof(OicUuid_t)); - - // Copy the resource string into context. - length = strlen(resource) + 1; - if(0 < length) + if (NULL == context || NULL == subjectId || NULL == resource) { - OICFree(context->resource); - context->resource = (char*)OICMalloc(length); - VERIFY_NON_NULL(TAG, context->resource, ERROR); - strncpy(context->resource, resource, length); - context->resource[length - 1] = '\0'; + return; } + memcpy(&context->subject, subjectId, sizeof(OicUuid_t)); + + // Copy the resource string into context. + length = sizeof(context->resource) - 1; + strncpy(context->resource, resource, length); + context->resource[length] = '\0'; + + // Assign the permission field. context->permission = requestedPermission; - -exit: - return; } /** * Check whether 'resource' is getting accessed within the valid time period. - * @param acl The ACL to check. - * @return - * true if access is within valid time period or if the period or recurrence is not present. - * false if period and recurrence present and the access is not within valid time period. + * + * @param acl is the ACL to check. + * + * @return true if access is within valid time period or if the period or recurrence is not present. + * false if period and recurrence present and the access is not within valid time period. */ -static bool IsAccessWithinValidTime(const OicSecAcl_t *acl) +static bool IsAccessWithinValidTime(const OicSecAce_t *ace) { #ifndef WITH_ARDUINO //Period & Recurrence not supported on Arduino due - //lack of absolute time - if(NULL== acl || NULL == acl->periods || 0 == acl->prdRecrLen) + //lack of absolute time + if (NULL== ace || NULL == ace->validities) { return true; } - for(size_t i = 0; i < acl->prdRecrLen; i++) + //periods & recurrences rules are paired. + if (NULL == ace->validities->recurrences) { - if(IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(acl->periods[i], - acl->recurrences[i])) + return false; + } + + OicSecValidity_t* validity = NULL; + LL_FOREACH(ace->validities, validity) + { + for(size_t i = 0; i < validity->recurrenceLen; i++) { - OC_LOG(INFO, TAG, "Access request is in allowed time period"); - return true; + if (IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(validity->period, + validity->recurrences[i])) + { + OIC_LOG(INFO, TAG, "Access request is in allowed time period"); + return true; + } } } - OC_LOG(INFO, TAG, "Access request is in invalid time period"); + OIC_LOG(ERROR, TAG, "Access request is in invalid time period"); return false; #else @@ -221,17 +447,25 @@ static bool IsAccessWithinValidTime(const OicSecAcl_t *acl) } /** - * Check whether 'resource' is in the passed ACL. - * @param resource The resource to search for. - * @param acl The ACL to check. + * Check whether 'resource' is in the passed ACE. + * + * @param resource is the resource being searched. + * @param ace is the ACE to check. + * * @return true if 'resource' found, otherwise false. */ - bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl) + static bool IsResourceInAce(const char *resource, const OicSecAce_t *ace) { - for(size_t n = 0; n < acl->resourcesLen; n++) - { - if(0 == strcmp(resource, acl->resources[n]) || // TODO null terms? - 0 == strcmp(WILDCARD_RESOURCE_URI, acl->resources[n])) + if (NULL== ace || NULL == resource) + { + return false; + } + + OicSecRsrc_t* rsrc = NULL; + LL_FOREACH(ace->resources, rsrc) + { + if (0 == strcmp(resource, rsrc->href) || // TODO null terms? + 0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href)) { return true; } @@ -239,50 +473,53 @@ static bool IsAccessWithinValidTime(const OicSecAcl_t *acl) return false; } + /** * Find ACLs containing context->subject. * Search each ACL for requested resource. - * If resource found, check for context->permission. + * If resource found, check for context->permission and period validity. + * If the ACL is not found locally and AMACL for the resource is found + * then sends the request to AMS service for the ACL. * Set context->retVal to result from first ACL found which contains * correct subject AND resource. - * - * @retval void */ -void ProcessAccessRequest(PEContext_t *context) +static void ProcessAccessRequest(PEContext_t *context) { - OC_LOG(INFO, TAG, "Entering ProcessAccessRequest()"); - if(NULL != context) + if (NULL != context) { - const OicSecAcl_t *currentAcl = NULL; - OicSecAcl_t *savePtr = NULL; + const OicSecAce_t *currentAce = NULL; + OicSecAce_t *savePtr = NULL; + + OIC_LOG_V(DEBUG, TAG, "Entering ProcessAccessRequest(%s)", context->resource); // Start out assuming subject not found. context->retVal = ACCESS_DENIED_SUBJECT_NOT_FOUND; + + // Loop through all ACLs with a matching Subject searching for the right + // ACL for this request. do { - OC_LOG(INFO, TAG, "ProcessAccessRequest(): getting ACL..."); - currentAcl = GetACLResourceData(context->subject, &savePtr); - if(NULL != currentAcl) + OIC_LOG_V(DEBUG, TAG, "%s: getting ACE..." ,__func__); + currentAce = GetACLResourceData(&context->subject, &savePtr); + + if (NULL != currentAce) { // Found the subject, so how about resource? - OC_LOG(INFO, TAG, "ProcessAccessRequest(): \ - found ACL matching subject."); + OIC_LOG_V(DEBUG, TAG, "%s:found ACE matching subject" ,__func__); + + // Subject was found, so err changes to Rsrc not found for now. context->retVal = ACCESS_DENIED_RESOURCE_NOT_FOUND; - OC_LOG(INFO, TAG, "ProcessAccessRequest(): \ - Searching for resource..."); - if(IsResourceInAcl(context->resource, currentAcl)) + OIC_LOG_V(DEBUG, TAG, "%s:Searching for resource..." ,__func__); + if (IsResourceInAce(context->resource, currentAce)) { - OC_LOG(INFO, TAG, "ProcessAccessRequest(): \ - found matching resource in ACL."); - context->matchingAclFound = true; + OIC_LOG_V(INFO, TAG, "%s:found matching resource in ACE" ,__func__); // Found the resource, so it's down to valid period & permission. context->retVal = ACCESS_DENIED_INVALID_PERIOD; - if(IsAccessWithinValidTime(currentAcl)) + if (IsAccessWithinValidTime(currentAce)) { context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION; - if(IsPermissionAllowingRequest(currentAcl->permission, \ - context->permission)) + if (IsPermissionAllowingRequest(currentAce->permission, context->permission)) { context->retVal = ACCESS_GRANTED; } @@ -291,45 +528,29 @@ void ProcessAccessRequest(PEContext_t *context) } else { - OC_LOG(INFO, TAG, "ProcessAccessRequest(): \ - no ACL found matching subject ."); + OIC_LOG_V(INFO, TAG, "%s:no ACL found matching subject for resource %s",__func__, context->resource); } - } - while((NULL != currentAcl) && (false == context->matchingAclFound)); + } while ((NULL != currentAce) && (ACCESS_GRANTED != context->retVal)); - if(IsAccessGranted(context->retVal)) + if (IsAccessGranted(context->retVal)) { - OC_LOG(INFO, TAG, "ProcessAccessRequest(): \ - Leaving ProcessAccessRequest(ACCESS_GRANTED)"); + OIC_LOG_V(INFO, TAG, "%s:Leaving ProcessAccessRequest(ACCESS_GRANTED)", __func__); } else { - OC_LOG(INFO, TAG, "ProcessAccessRequest(): \ - Leaving ProcessAccessRequest(ACCESS_DENIED)"); + OIC_LOG_V(INFO, TAG, "%s:Leaving ProcessAccessRequest(ACCESS_DENIED)", __func__); } } else { - OC_LOG(INFO, TAG, "ProcessAccessRequest(): \ - Leaving ProcessAccessRequest(context is NULL)"); + OIC_LOG_V(ERROR, TAG, "%s:Leaving ProcessAccessRequest(context is NULL)", __func__); } - } -/** - * Check whether a request should be allowed. - * @param context Pointer to (Initialized) Policy Engine context to use. - * @param subjectId Pointer to Id of the requesting entity. - * @param resource Pointer to URI of Resource being requested. - * @param permission Requested permission. - * @return ACCESS_GRANTED if request should go through, - * otherwise some flavor of ACCESS_DENIED - */ -SRMAccessResponse_t CheckPermission( - PEContext_t *context, - const OicUuid_t *subjectId, - const char *resource, - const uint16_t requestedPermission) +SRMAccessResponse_t CheckPermission(PEContext_t *context, + const OicUuid_t *subjectId, + const char *resource, + const uint16_t requestedPermission) { SRMAccessResponse_t retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR; @@ -338,33 +559,95 @@ SRMAccessResponse_t CheckPermission( VERIFY_NON_NULL(TAG, resource, ERROR); // Each state machine context can only be processing one request at a time. - // Therefore if the context is not in AWAITING_REQUEST state, return error. - // Otherwise, change to BUSY state and begin processing request. - if(AWAITING_REQUEST == context->state) - { - SetPolicyEngineState(context, BUSY); - CopyParamsToContext(context, subjectId, resource, requestedPermission); - // Before doing any processing, check if request coming - // from DevOwner and if so, always GRANT. - if(IsRequestFromDevOwner(context)) + // Therefore if the context is not in AWAITING_REQUEST or AWAITING_AMS_RESPONSE + // state, return error. Otherwise, change to BUSY state and begin processing request. + if (AWAITING_REQUEST == context->state || AWAITING_AMS_RESPONSE == context->state) + { + if (AWAITING_REQUEST == context->state) + { + SetPolicyEngineState(context, BUSY); + CopyParamsToContext(context, subjectId, resource, requestedPermission); + } + + // Before doing any ACL processing, check if request a) coming + // from DevOwner AND b) the device is in Ready for OTM or Reset state + // (which in IoTivity is equivalent to isOp == false && owned == false) + // AND c) the request is for a SVR resource. + // If all 3 conditions are met, grant request. + bool isDeviceOwned = true; // default to value that will not grant access + if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned)) // if runtime error, don't grant + { + context->retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR; + } + // If we were able to get the value of doxm->isOwned, proceed with + // test for implicit access... + else if (IsRequestFromDevOwner(context) // if from DevOwner + && (GetPstatIsop() == false) // AND if pstat->isOp == false + && (isDeviceOwned == false) // AND if doxm->isOwned == false + && (context->resourceType != NOT_A_SVR_RESOURCE)) // AND if SVR type + { + context->retVal = ACCESS_GRANTED; + } + // If not granted via DevOwner status and not a subowner, + // then check if request is for a SVR and coming from rowner + else if (IsRequestFromResourceOwner(context)) { context->retVal = ACCESS_GRANTED; } +#ifdef MULTIPLE_OWNER + //Then check if request from SubOwner + else if(IsRequestFromSubOwner(context)) + { + if(IsValidRequestFromSubOwner(context)) + { + context->retVal = ACCESS_GRANTED; + } + } +#endif //MULTIPLE_OWNER + // Else request is a "normal" request that must be tested against ACL else { + OicUuid_t saveSubject = {.id={0}}; + bool isSubEmpty = IsRequestSubjectEmpty(context); + ProcessAccessRequest(context); - // If matching ACL not found, and subject != wildcard, try wildcard. - if((false == context->matchingAclFound) && \ - (false == IsWildCardSubject(context->subject))) + + // If access not already granted, and requested subject != wildcard, + // try looking for a wildcard ACE that grants access. + if ((ACCESS_GRANTED != context->retVal) && \ + (false == IsWildCardSubject(&context->subject))) { - OICFree(context->subject); - context->subject = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t)); - VERIFY_NON_NULL(TAG, context->subject, ERROR); - memcpy(context->subject, &WILDCARD_SUBJECT_ID, - sizeof(OicUuid_t)); + //Saving subject for Amacl check + memcpy(&saveSubject, &context->subject,sizeof(OicUuid_t)); + + //Setting context subject to WILDCARD_SUBJECT_ID + //TODO: change ProcessAccessRequest method signature to + //ProcessAccessRequest(context, subject) so that context + //subject is not tempered. + memset(&context->subject, 0, sizeof(context->subject)); + memcpy(&context->subject, &WILDCARD_SUBJECT_ID,sizeof(OicUuid_t)); ProcessAccessRequest(context); // TODO anonymous subj can result // in confusing err code return. } + + //No local ACE found for the request so checking Amacl resource + if (ACCESS_GRANTED != context->retVal) + { + //If subject is not empty then restore the original subject + //else keep the subject to WILDCARD_SUBJECT_ID + if(!isSubEmpty) + { + memcpy(&context->subject, &saveSubject, sizeof(OicUuid_t)); + } + + //FoundAmaclForRequest method checks for Amacl and fills up + //context->amsMgrContext->amsDeviceId with the AMS deviceId + //if Amacl was found for the requested resource. + if(FoundAmaclForRequest(context)) + { + ProcessAMSRequest(context); + } + } } } else @@ -374,39 +657,40 @@ SRMAccessResponse_t CheckPermission( // Capture retVal before resetting state for next request. retVal = context->retVal; - SetPolicyEngineState(context, AWAITING_REQUEST); + + if (!context->amsProcessing) + { + OIC_LOG(INFO, TAG, "Resetting PE context and PE State to AWAITING_REQUEST"); + SetPolicyEngineState(context, AWAITING_REQUEST); + } exit: return retVal; } -/** - * Initialize the Policy Engine. Call this before calling CheckPermission(). - * @param context Pointer to Policy Engine context to initialize. - * @return OC_STACK_OK for Success, otherwise some error value - */ OCStackResult InitPolicyEngine(PEContext_t *context) { - if(NULL != context) + if(NULL == context) { - SetPolicyEngineState(context, AWAITING_REQUEST); + return OC_STACK_ERROR; + } + + context->amsMgrContext = (AmsMgrContext_t *)OICCalloc(1, sizeof(AmsMgrContext_t)); + if(NULL == context->amsMgrContext) + { + return OC_STACK_ERROR; } + SetPolicyEngineState(context, AWAITING_REQUEST); return OC_STACK_OK; } -/** - * De-Initialize the Policy Engine. Call this before exiting to allow Policy - * Engine to do cleanup on context. - * @param context Pointer to Policy Engine context to de-initialize. - * @return none - */ void DeInitPolicyEngine(PEContext_t *context) { if(NULL != context) { SetPolicyEngineState(context, STOPPED); + OICFree(context->amsMgrContext); } - return; }