// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <string.h>
#include "oic_malloc.h"
#include "policyengine.h"
#include "srmutility.h"
#include "doxmresource.h"
#include "iotvticalendar.h"
+#include <string.h>
#define TAG "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;
}
/**
- * Compares two OicUuid_t structs.
- *
+ * @brief Compares two OicUuid_t structs.
* @return true if the two OicUuid_t structs are equal, else false.
*/
-static bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId)
+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 true;
}
+/**
+ * Set the state and clear other stateful context vars.
+ */
void SetPolicyEngineState(PEContext_t *context, const PEState_t state)
{
- if (NULL == context)
+ if(NULL == context)
{
return;
}
}
/**
- * Compare the request's subject to DevOwner.
+ * @brief Compare the request's subject to DevOwner.
*
- * @return true if context->subjectId == GetDoxmDevOwner(), else false.
+ * @return true if context->subjectId == GetDoxmDevOwner(), else false
*/
-static bool IsRequestFromDevOwner(PEContext_t *context)
+bool IsRequestFromDevOwner(PEContext_t *context)
{
bool retVal = false;
OicUuid_t owner;
return retVal;
}
+
inline static bool IsRequestSubjectEmpty(PEContext_t *context)
{
OicUuid_t emptySubject = {.id={}};
true : false;
}
+
/**
* Bitwise check to see if 'permission' contains 'request'.
- *
- * @param permission is the allowed CRUDN permission.
- * @param request is the CRUDN permission being requested.
- *
+ * @param permission The allowed CRUDN permission.
+ * @param request The CRUDN permission being requested.
* @return true if 'permission' bits include all 'request' bits.
*/
static inline bool IsPermissionAllowingRequest(const uint16_t permission,
const uint16_t request)
{
- if (request == (request & permission))
+ if(request == (request & permission))
{
return true;
}
/**
* 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)
/**
* Copy the subject, resource and permission into the context fields.
*/
-static void CopyParamsToContext(PEContext_t *context,
- const OicUuid_t *subjectId,
- const char *resource,
- const uint16_t requestedPermission)
+void CopyParamsToContext(
+ PEContext_t *context,
+ const OicUuid_t *subjectId,
+ const char *resource,
+ const uint16_t requestedPermission)
{
size_t length = 0;
- if (NULL == context || NULL == subjectId || NULL == resource)
+ if(NULL == context || NULL == subjectId || NULL == resource)
{
return;
}
// Copy the resource string into context.
length = strlen(resource) + 1;
- if (0 < length)
+ if(0 < length)
{
strncpy(context->resource, resource, length);
context->resource[length - 1] = '\0';
context->permission = requestedPermission;
}
+
/**
* Check whether 'resource' is getting accessed within the 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.
+ * @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.
*/
static bool IsAccessWithinValidTime(const OicSecAcl_t *acl)
{
#ifndef WITH_ARDUINO //Period & Recurrence not supported on Arduino due
//lack of absolute time
- if (NULL== acl || NULL == acl->periods || 0 == acl->prdRecrLen)
+ if(NULL== acl || NULL == acl->periods || 0 == acl->prdRecrLen)
{
return true;
}
//periods & recurrences rules are paired.
- if (NULL == acl->recurrences)
+ if(NULL == acl->recurrences)
{
return false;
}
- for (size_t i = 0; i < acl->prdRecrLen; i++)
+ for(size_t i = 0; i < acl->prdRecrLen; i++)
{
- if (IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(acl->periods[i],
+ if(IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(acl->periods[i],
acl->recurrences[i]))
{
OIC_LOG(INFO, TAG, "Access request is in allowed time period");
/**
* Check whether 'resource' is in the passed ACL.
- *
- * @param resource is the resource being searched.
- * @param acl is the ACL to check.
- *
+ * @param resource The resource to search for.
+ * @param acl The ACL to check.
* @return true if 'resource' found, otherwise false.
*/
- static bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl)
+ bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl)
{
- if (NULL== acl || NULL == resource)
+ if(NULL== acl || NULL == resource)
{
return false;
}
- for (size_t n = 0; n < acl->resourcesLen; n++)
+ 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(0 == strcmp(resource, acl->resources[n]) || // TODO null terms?
+ 0 == strcmp(WILDCARD_RESOURCE_URI, acl->resources[n]))
{
return true;
}
* Search each ACL for requested resource.
* 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.
+ * 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
*/
-static void ProcessAccessRequest(PEContext_t *context)
+void ProcessAccessRequest(PEContext_t *context)
{
OIC_LOG(DEBUG, TAG, "Entering ProcessAccessRequest()");
- if (NULL != context)
+ if(NULL != context)
{
const OicSecAcl_t *currentAcl = NULL;
OicSecAcl_t *savePtr = NULL;
OIC_LOG_V(DEBUG, TAG, "%s: getting ACL..." ,__func__);
currentAcl = GetACLResourceData(&context->subject, &savePtr);
- if (NULL != currentAcl)
+ if(NULL != currentAcl)
{
// Found the subject, so how about resource?
OIC_LOG_V(DEBUG, TAG, "%s:found ACL matching subject" ,__func__);
// Subject was found, so err changes to Rsrc not found for now.
context->retVal = ACCESS_DENIED_RESOURCE_NOT_FOUND;
OIC_LOG_V(DEBUG, TAG, "%s:Searching for resource..." ,__func__);
- if (IsResourceInAcl(context->resource, currentAcl))
+ if(IsResourceInAcl(context->resource, currentAcl))
{
OIC_LOG_V(INFO, TAG, "%s:found matching resource in ACL" ,__func__);
context->matchingAclFound = true;
// Found the resource, so it's down to valid period & permission.
context->retVal = ACCESS_DENIED_INVALID_PERIOD;
- if (IsAccessWithinValidTime(currentAcl))
+ if(IsAccessWithinValidTime(currentAcl))
{
context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION;
- if (IsPermissionAllowingRequest(currentAcl->permission, context->permission))
+ if(IsPermissionAllowingRequest(currentAcl->permission, context->permission))
{
context->retVal = ACCESS_GRANTED;
}
{
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 != currentAcl) && (false == context->matchingAclFound));
- if (IsAccessGranted(context->retVal))
+ if(IsAccessGranted(context->retVal))
{
OIC_LOG_V(INFO, TAG, "%s:Leaving ProcessAccessRequest(ACCESS_GRANTED)", __func__);
}
}
}
-SRMAccessResponse_t CheckPermission(PEContext_t *context,
- const OicUuid_t *subjectId,
- const char *resource,
- const uint16_t requestedPermission)
+/**
+ * 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 retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR;
// Each state machine context can only be processing one request at a time.
// 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 || AWAITING_AMS_RESPONSE == context->state)
{
- if (AWAITING_REQUEST == context->state)
+ 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))
+ if(IsRequestFromDevOwner(context))
{
context->retVal = ACCESS_GRANTED;
}
ProcessAccessRequest(context);
// If matching ACL not found, and subject != wildcard, try wildcard.
- if ((false == context->matchingAclFound) && \
+ if((false == context->matchingAclFound) && \
(false == IsWildCardSubject(&context->subject)))
{
//Saving subject for Amacl check
}
//No local ACE found for the request so checking Amacl resource
- if (ACCESS_GRANTED != context->retVal)
+ if(ACCESS_GRANTED != context->retVal)
{
//If subject is not empty then restore the original subject
//else keep the subject to WILDCARD_SUBJECT_ID
// Capture retVal before resetting state for next request.
retVal = context->retVal;
- if (!context->amsProcessing)
+ if(!context->amsProcessing)
{
OIC_LOG(INFO, TAG, "Resetting PE context and PE State to AWAITING_REQUEST");
SetPolicyEngineState(context, AWAITING_REQUEST);
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)
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)