From 86daa1325dad4e2266299de9b3ea4df334a777fa Mon Sep 17 00:00:00 2001 From: Shilpa Sodani Date: Tue, 14 Jul 2015 15:53:52 -0700 Subject: [PATCH] Enabled Period & Recurrence in ACL resource. Andded marshalling and unmarshalling code for Period and Recurrence properties of ACL. Updated Policy engine to consider period and recurrence while allowing access to resource. Updated server json database. Change-Id: I31181e6972f0bbf440c17521d20d5058a2621afa Signed-off-by: Shilpa Sodani Reviewed-on: https://gerrit.iotivity.org/gerrit/1655 Tested-by: jenkins-iotivity Reviewed-by: Sachin Agrawal --- .../security/include/internal/srmresourcestrings.h | 2 + .../security/include/securevirtualresourcetypes.h | 10 +- resource/csdk/security/src/aclresource.c | 102 ++++++++++++++++++++- resource/csdk/security/src/policyengine.c | 67 +++++++++++--- resource/csdk/security/src/srmresourcestrings.c | 4 +- .../samples/linux/secure/oic_svr_db_server.json | 32 ++++++- 6 files changed, 194 insertions(+), 23 deletions(-) diff --git a/resource/csdk/security/include/internal/srmresourcestrings.h b/resource/csdk/security/include/internal/srmresourcestrings.h index f2f1e2a..53e1518 100644 --- a/resource/csdk/security/include/internal/srmresourcestrings.h +++ b/resource/csdk/security/include/internal/srmresourcestrings.h @@ -74,6 +74,8 @@ extern const char * OIC_JSON_CREDTYPE_NAME; extern const char * OIC_JSON_PUBLICDATA_NAME; extern const char * OIC_JSON_PRIVATEDATA_NAME; extern const char * OIC_JSON_PERIOD_NAME; +extern const char * OIC_JSON_PERIODS_NAME; +extern const char * OIC_JSON_RECURRENCES_NAME; extern const char * OIC_JSON_ISOP_NAME; extern const char * OIC_JSON_COMMIT_HASH_NAME; extern const char * OIC_JSON_DEVICE_ID_NAME; diff --git a/resource/csdk/security/include/securevirtualresourcetypes.h b/resource/csdk/security/include/securevirtualresourcetypes.h index ec7029c..0ae10fa 100644 --- a/resource/csdk/security/include/securevirtualresourcetypes.h +++ b/resource/csdk/security/include/securevirtualresourcetypes.h @@ -58,7 +58,9 @@ extern "C" { #define SUBJECT_NOT_FOUND_DEF (1 << 3) #define RESOURCE_NOT_FOUND_DEF (1 << 4) #define POLICY_ENGINE_ERROR_DEF (1 << 5) +#define INVALID_PERIOD_DEF (1 << 6) #define REASON_MASK_DEF (INSUFFICIENT_PERMISSION_DEF | \ + INVALID_PERIOD_DEF | \ SUBJECT_NOT_FOUND_DEF | \ RESOURCE_NOT_FOUND_DEF | \ POLICY_ENGINE_ERROR_DEF) @@ -102,6 +104,8 @@ typedef enum { ACCESS_GRANTED = ACCESS_GRANTED_DEF, ACCESS_DENIED = ACCESS_DENIED_DEF, + ACCESS_DENIED_INVALID_PERIOD = ACCESS_DENIED_DEF + | INVALID_PERIOD_DEF, ACCESS_DENIED_INSUFFICIENT_PERMISSION = ACCESS_DENIED_DEF | INSUFFICIENT_PERMISSION_DEF, ACCESS_DENIED_SUBJECT_NOT_FOUND = ACCESS_DENIED_DEF @@ -286,9 +290,9 @@ struct OicSecAcl size_t resourcesLen; // the number of elts in Resources char **resources; // 1:R:M:Y:String uint16_t permission; // 2:R:S:Y:UINT16 - size_t periodsLen; // the number of elts in Periods - char **periods; // 3:R:M*:N:String (<--M*; see Spec) - char *recurrences; // 5:R:M:N:String + size_t prdRecrLen; // the number of elts in Periods + char **periods; // 3:R:M*:N:String (<--M*; see Spec) + char **recurrences; // 5:R:M:N:String size_t ownersLen; // the number of elts in Owners OicUuid_t *owners; // 8:R:M:Y:oic.uuid // NOTE: we are using UUID for Owners instead of Svc type for mid-April diff --git a/resource/csdk/security/src/aclresource.c b/resource/csdk/security/src/aclresource.c index a1afef8..7da0f85 100644 --- a/resource/csdk/security/src/aclresource.c +++ b/resource/csdk/security/src/aclresource.c @@ -23,6 +23,7 @@ #include "ocstack.h" #include "logger.h" #include "oic_malloc.h" +#include "oic_string.h" #include "cJSON.h" #include "base64.h" #include "resourcemanager.h" @@ -58,6 +59,15 @@ void DeleteACLList(OicSecAcl_t* acl) } OICFree(aclTmp1->resources); + //Clean Period & Recurrence + for(i = 0; i < aclTmp1->prdRecrLen; i++) + { + OICFree(aclTmp1->periods[i]); + OICFree(aclTmp1->recurrences[i]); + } + OICFree(aclTmp1->periods); + OICFree(aclTmp1->recurrences); + // Clean Owners OICFree(aclTmp1->owners); @@ -123,6 +133,34 @@ char * BinToAclJSON(const OicSecAcl_t * acl) // Permissions -- Mandatory cJSON_AddNumberToObject (jsonAcl, OIC_JSON_PERMISSION_NAME, acl->permission); + //Period & Recurrence -- Not Mandatory + if(0 != acl->prdRecrLen) + { + cJSON *jsonPeriodArray = NULL; + cJSON_AddItemToObject (jsonAcl, OIC_JSON_PERIODS_NAME, + jsonPeriodArray = cJSON_CreateArray()); + VERIFY_NON_NULL(TAG, jsonPeriodArray, ERROR); + for (size_t i = 0; i < acl->prdRecrLen; i++) + { + cJSON_AddItemToArray (jsonPeriodArray, + cJSON_CreateString(acl->periods[i])); + } + } + + //Recurrence -- Not Mandatory + if(0 != acl->prdRecrLen && acl->recurrences) + { + cJSON *jsonRecurArray = NULL; + cJSON_AddItemToObject (jsonAcl, OIC_JSON_RECURRENCES_NAME, + jsonRecurArray = cJSON_CreateArray()); + VERIFY_NON_NULL(TAG, jsonRecurArray, ERROR); + for (size_t i = 0; i < acl->prdRecrLen; i++) + { + cJSON_AddItemToArray (jsonRecurArray, + cJSON_CreateString(acl->recurrences[i])); + } + } + // Owners -- Mandatory cJSON *jsonOwnrArray = NULL; cJSON_AddItemToObject (jsonAcl, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray()); @@ -229,15 +267,71 @@ OicSecAcl_t * JSONToAclBin(const char * jsonStr) jsonObjLen = strlen(jsonRsrc->valuestring) + 1; acl->resources[idxx] = (char*)OICMalloc(jsonObjLen); VERIFY_NON_NULL(TAG, (acl->resources[idxx]), ERROR); - strncpy(acl->resources[idxx], jsonRsrc->valuestring, jsonObjLen); + OICStrcpy(acl->resources[idxx], jsonObjLen, jsonRsrc->valuestring); } while ( ++idxx < acl->resourcesLen); // Permissions -- Mandatory - jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_PERMISSION_NAME); + jsonObj = cJSON_GetObjectItem(jsonAcl, + OIC_JSON_PERMISSION_NAME); VERIFY_NON_NULL(TAG, jsonObj, ERROR); VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR); acl->permission = jsonObj->valueint; + //Period -- Not Mandatory + cJSON *jsonPeriodObj = cJSON_GetObjectItem(jsonAcl, + OIC_JSON_PERIODS_NAME); + if(jsonPeriodObj) + { + VERIFY_SUCCESS(TAG, cJSON_Array == jsonPeriodObj->type, + ERROR); + acl->prdRecrLen = cJSON_GetArraySize(jsonPeriodObj); + if(acl->prdRecrLen > 0) + { + acl->periods = (char**)OICCalloc(acl->prdRecrLen, + sizeof(char*)); + VERIFY_NON_NULL(TAG, acl->periods, ERROR); + + cJSON *jsonPeriod = NULL; + for(size_t i = 0; i < acl->prdRecrLen; i++) + { + jsonPeriod = cJSON_GetArrayItem(jsonPeriodObj, i); + VERIFY_NON_NULL(TAG, jsonPeriod, ERROR); + + jsonObjLen = strlen(jsonPeriod->valuestring) + 1; + acl->periods[i] = (char*)OICMalloc(jsonObjLen); + VERIFY_NON_NULL(TAG, acl->periods[i], ERROR); + OICStrcpy(acl->periods[i], jsonObjLen, + jsonPeriod->valuestring); + } + } + } + + //Recurrence -- Not mandatory + cJSON *jsonRecurObj = cJSON_GetObjectItem(jsonAcl, + OIC_JSON_RECURRENCES_NAME); + if(jsonRecurObj) + { + VERIFY_SUCCESS(TAG, cJSON_Array == jsonRecurObj->type, + ERROR); + if(acl->prdRecrLen > 0) + { + acl->recurrences = (char**)OICCalloc(acl->prdRecrLen, + sizeof(char*)); + VERIFY_NON_NULL(TAG, acl->recurrences, ERROR); + + cJSON *jsonRecur = NULL; + for(size_t i = 0; i < acl->prdRecrLen; i++) + { + jsonRecur = cJSON_GetArrayItem(jsonRecurObj, i); + jsonObjLen = strlen(jsonRecur->valuestring) + 1; + acl->recurrences[i] = (char*)OICMalloc(jsonObjLen); + VERIFY_NON_NULL(TAG, acl->recurrences[i], ERROR); + OICStrcpy(acl->recurrences[i], jsonObjLen, + jsonRecur->valuestring); + } + } + } + // Owners -- Mandatory jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_OWNERS_NAME); VERIFY_NON_NULL(TAG, jsonObj, ERROR); @@ -450,11 +544,11 @@ OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl) size_t len = strlen(rsrcs[i]) + 1; acl->resources[i] = (char*)OICMalloc(len * sizeof(char)); VERIFY_NON_NULL(TAG, (acl->resources[i]), ERROR); - strncpy(acl->resources[i], rsrcs[i], len); + OICStrcpy(acl->resources[i], len, rsrcs[i]); } acl->permission = PERMISSION_READ; - acl->periodsLen = 0; + acl->prdRecrLen = 0; acl->periods = NULL; acl->recurrences = NULL; diff --git a/resource/csdk/security/src/policyengine.c b/resource/csdk/security/src/policyengine.c index c39814d..9a61f00 100644 --- a/resource/csdk/security/src/policyengine.c +++ b/resource/csdk/security/src/policyengine.c @@ -27,6 +27,7 @@ #include "aclresource.h" #include "srmutility.h" #include "doxmresource.h" +#include "iotvticalendar.h" #include #define TAG PCF("SRM-PE") @@ -187,23 +188,56 @@ exit: } /** - * Check whether 'resource' is in the passed ACL. - * @param resource The resource to search for. + * Check whether 'resource' is getting accessed within the valid time period. * @param acl The ACL to check. - * @return true if 'resource' found, otherwise false. + * @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. */ - bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl) - { - for(size_t n = 0; n < acl->resourcesLen; n++) +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) + { + return true; + } + + for(size_t i = 0; i < acl->prdRecrLen; i++) { - if(0 == strcmp(resource, acl->resources[n]) || // TODO null terms? - 0 == strcmp(WILDCARD_RESOURCE_URI, acl->resources[n])) + if(IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(acl->periods[i], + acl->recurrences[i])) { + OC_LOG(INFO, TAG, PCF("Access request is in allowed time period")); return true; } } + OC_LOG(INFO, TAG, PCF("Access request is in invalid time period")); return false; - } + +#else + return true; +#endif +} + +/** + * Check whether 'resource' is in the passed ACL. + * @param resource The resource to search for. + * @param acl The ACL to check. + * @return true if 'resource' found, otherwise false. + */ + bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl) +{ + 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])) + { + return true; + } + } + return false; +} /** * Find ACLs containing context->subject. @@ -241,12 +275,17 @@ void ProcessAccessRequest(PEContext_t *context) OC_LOG(INFO, TAG, PCF("ProcessAccessRequest(): \ found matching resource in ACL.")); context->matchingAclFound = true; - // Found the resource, so it's down to permission. - context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION; - if(IsPermissionAllowingRequest(currentAcl->permission, \ - context->permission)) + + // Found the resource, so it's down to valid period & permission. + context->retVal = ACCESS_DENIED_INVALID_PERIOD; + if(IsAccessWithinValidTime(currentAcl)) { - context->retVal = ACCESS_GRANTED; + context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION; + if(IsPermissionAllowingRequest(currentAcl->permission, \ + context->permission)) + { + context->retVal = ACCESS_GRANTED; + } } } } diff --git a/resource/csdk/security/src/srmresourcestrings.c b/resource/csdk/security/src/srmresourcestrings.c index df67800..1930002 100644 --- a/resource/csdk/security/src/srmresourcestrings.c +++ b/resource/csdk/security/src/srmresourcestrings.c @@ -79,9 +79,11 @@ const char * OIC_JSON_ROLEIDS_NAME = "roleid"; const char * OIC_JSON_CREDTYPE_NAME = "credtyp"; const char * OIC_JSON_PUBLICDATA_NAME = "pbdata"; const char * OIC_JSON_PRIVATEDATA_NAME = "pvdata"; -const char * OIC_JSON_PERIOD_NAME = "period"; const char * OIC_JSON_SERVICE_DEVICE_ID = "svcdid"; const char * OIC_JSON_SERVICE_TYPE = "svct"; +const char * OIC_JSON_PERIOD_NAME = "prd"; +const char * OIC_JSON_PERIODS_NAME = "prds"; +const char * OIC_JSON_RECURRENCES_NAME = "recurs"; OicUuid_t WILDCARD_SUBJECT_ID = {"*"}; size_t WILDCARD_SUBJECT_ID_LEN = 1; diff --git a/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json b/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json index 7346ebc..42b2c29 100644 --- a/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json +++ b/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json @@ -28,6 +28,22 @@ "rsrc": ["/a/led"], "perms": 6, "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] + }, + { + "sub": "MTExMTIyMjIzMzMzNDQ0NA==", + "rsrc": ["/a/led"], + "perms": 6, + "prds" : ["20150630T060000/20150630T220000", "20150630T060000/20150630T200000"], + "recurs" : ["FREQ=DAILY; BYDAY=MO, WE, FR", "FREQ=DAILY; BYDAY=TU, TH; UNTIL=20160630"], + "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] + }, + { + "sub": "Nzc3Nzc3Nzc3Nzc3Nzc3Nw==", + "rsrc": ["/a/led"], + "perms": 6, + "prds" : ["20150630T060000/20150630T220000"], + "recurs" : ["FREQ=DAILY; UNTIL=20150630"], + "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] } ], "pstat": { @@ -44,7 +60,7 @@ "oxmsel": 0, "owned": true, "deviceid": "MTExMTExMTExMTExMTExMQ==", - "ownr": "MjIyMjIyMjIyMjIyMjIyMg==" + "ownr": "YWRtaW5EZXZpY2VVVUlEAA==" }, "cred": [{ "credid": 1, @@ -52,5 +68,19 @@ "credtyp": 1, "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==", "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] + }, + { + "credid": 2, + "sub": "MTExMTIyMjIzMzMzNDQ0NA==", + "credtyp": 1, + "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==", + "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] + }, + { + "credid": 3, + "sub": "Nzc3Nzc3Nzc3Nzc3Nzc3Nw==", + "credtyp": 1, + "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==", + "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="] }] } -- 2.7.4