X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fsecurity%2Fsrc%2Fpolicyengine.c;h=779688c4deb4e2b4e43a004c323dd0df62d12a24;hb=841c433b9e28239bd8e29e46f23d1269514f619e;hp=fd9f2eda5e3f1b32868c97138b64731b6d666b3e;hpb=1eaa05e4bb9c3b18087f908dfb88f37514091eac;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/security/src/policyengine.c b/resource/csdk/security/src/policyengine.c index fd9f2ed..779688c 100644 --- a/resource/csdk/security/src/policyengine.c +++ b/resource/csdk/security/src/policyengine.c @@ -37,7 +37,7 @@ #include "amaclresource.h" #include "credresource.h" -#define TAG "SRM-PE" +#define TAG "OIC_SRM_PE" uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method) { @@ -47,10 +47,15 @@ uint16_t GetPermissionFromCAMethod_t(const CAMethod_t 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; @@ -99,7 +104,6 @@ void SetPolicyEngineState(PEContext_t *context, const PEState_t state) 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; @@ -147,6 +151,95 @@ static bool IsRequestFromDevOwner(PEContext_t *context) return retVal; } + +#ifdef MULTIPLE_OWNER +/** + * Compare the request's subject to SubOwner. + * + * @return true if context->subjectId exist subowner list, else false. + */ +static bool IsRequestFromSubOwner(PEContext_t *context) +{ + bool retVal = false; + + if(NULL == context) + { + 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 @@ -392,12 +485,13 @@ static bool IsAccessWithinValidTime(const OicSecAce_t *ace) */ static void ProcessAccessRequest(PEContext_t *context) { - OIC_LOG(DEBUG, TAG, "Entering ProcessAccessRequest()"); if (NULL != context) { 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; @@ -419,7 +513,6 @@ static void ProcessAccessRequest(PEContext_t *context) if (IsResourceInAce(context->resource, currentAce)) { OIC_LOG_V(INFO, TAG, "%s:found matching resource in ACE" ,__func__); - context->matchingAclFound = true; // Found the resource, so it's down to valid period & permission. context->retVal = ACCESS_DENIED_INVALID_PERIOD; @@ -437,7 +530,7 @@ static void ProcessAccessRequest(PEContext_t *context) { OIC_LOG_V(INFO, TAG, "%s:no ACL found matching subject for resource %s",__func__, context->resource); } - } while ((NULL != currentAce) && (false == context->matchingAclFound)); + } while ((NULL != currentAce) && (ACCESS_GRANTED != context->retVal)); if (IsAccessGranted(context->retVal)) { @@ -476,17 +569,41 @@ SRMAccessResponse_t CheckPermission(PEContext_t *context, CopyParamsToContext(context, subjectId, resource, requestedPermission); } - // Before doing any processing, check if request coming - // from DevOwner and if so, always GRANT. - if (IsRequestFromDevOwner(context)) + // 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; } - // Then check if request is for a SVR and coming from rowner + // 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 { @@ -495,8 +612,9 @@ SRMAccessResponse_t CheckPermission(PEContext_t *context, ProcessAccessRequest(context); - // If matching ACL not found, and subject != wildcard, try wildcard. - if ((false == context->matchingAclFound) && \ + // 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))) { //Saving subject for Amacl check