[IOT-2224] ace2 Resource "wc" type
authorNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Sat, 13 May 2017 04:26:48 +0000 (21:26 -0700)
committerNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Tue, 16 May 2017 14:46:44 +0000 (14:46 +0000)
Implement phase-out of "*" href and replace with
"wc" types:

"*" = ALL_RESOURCES
"+" = ALL_DISCOVERABLE
"-" = ALL_NON_DISCOVERABLE

Add support for "wc" type to Policy Engine.

Change-Id: I738110de4d132dc5e60c73c79ad8e6b0d535d8d5
Signed-off-by: Nathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/19861
Reviewed-by: Kevin Kane <kkane@microsoft.com>
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
resource/csdk/security/include/internal/secureresourcemanager.h
resource/csdk/security/include/securevirtualresourcetypes.h
resource/csdk/security/src/aclresource.c
resource/csdk/security/src/policyengine.c
resource/csdk/security/src/secureresourcemanager.c
resource/csdk/security/tool/json2cbor.c

index baaff54..bec8ed2 100644 (file)
@@ -51,6 +51,7 @@ typedef struct SRMRequestContext
     const CARequestInfo_t   *requestInfo;                       // ptr to info for this request
     bool                    secureChannel;                      // Was request recv'd over secure channel?
     bool                    slowResponseSent;                   // Is a full response still needed?
+    OicSecDiscoverable_t    discoverable;                       // Is resource discoverable?
     SubjectIdentityType_t   subjectIdType;                      // The type of Subject ID in this
                                                                 // request.
     OicUuid_t               subjectUuid;                        // The UUID of the Subject (valid
index feef24f..b695844 100644 (file)
@@ -467,6 +467,13 @@ typedef enum
     OIC_SEC_ACL_V2 = 2
 } OicSecAclVersion_t;
 
+typedef enum
+{
+    DISCOVERABLE_NOT_KNOWN = 0,
+    DISCOVERABLE_TRUE = 1,
+    DISCOVERABLE_FALSE = 2
+} OicSecDiscoverable_t;
+
 #define OIC_SEC_ACL_LATEST OIC_SEC_ACL_V2
 
 typedef enum
index 1515783..6300d0b 100644 (file)
@@ -665,11 +665,28 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl,
             {
 
                 CborEncoder rMap;
-                size_t rsrcMapSize = ACL_RESOURCE_MAP_SIZE;
-                if(rsrc->rel)
+                size_t rsrcMapSize = 0;
+                if (NULL != rsrc->href)
+                {
+                    rsrcMapSize++;
+                }
+                if (rsrc->typeLen > 0)
+                {
+                    rsrcMapSize++;
+                }
+                if (rsrc->interfaceLen > 0)
                 {
                     rsrcMapSize++;
                 }
+                if (NULL != rsrc->rel)
+                {
+                    rsrcMapSize++;
+                }
+                if (NO_WILDCARD != rsrc->wildcard)
+                {
+                    rsrcMapSize++;
+                }
+                OIC_LOG_V(DEBUG, TAG, "%s resource map size = %d.", __func__, rsrcMapSize);
 
                 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, rsrcMapSize);
                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Map.");
@@ -733,7 +750,7 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl,
                 }
 
                 // rel
-                if(rsrc->rel)
+                if(NULL != rsrc->rel)
                 {
                     cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
                             strlen(OIC_JSON_REL_NAME));
@@ -759,10 +776,10 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl,
                             wcstring = OIC_JSON_WC_PLUS_NAME;
                             break;
                             case ALL_NON_DISCOVERABLE:
-                            wcstring = OIC_JSON_WC_PLUS_NAME;
+                            wcstring = OIC_JSON_WC_MINUS_NAME;
                             break;
                             case ALL_RESOURCES:
-                            wcstring = OIC_JSON_WC_PLUS_NAME;
+                            wcstring = OIC_JSON_WC_ASTERISK_NAME;
                             break;
                             default:
                             OIC_LOG_V(ERROR, TAG, "%s: unknown ACE2 wildcard type.", __func__);
@@ -1690,6 +1707,20 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
                                                 cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &tempLen, NULL);
                                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
                                                 OIC_LOG_V(DEBUG, TAG, "%s found href = %s.", __func__, rsrc->href);
+                                                // OCF 1.0 shouldn't use "*" href even though it's supported; instead,
+                                                // use "wc" object.
+                                                if (0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
+                                                {
+                                                    free(rsrc->href);
+                                                    rsrc->href = NULL;
+                                                    rsrc->wildcard = ALL_RESOURCES;
+                                                    OIC_LOG_V(DEBUG, TAG, "%s: replaced \"*\" href with wildcard = ALL_RESOURCES.",
+                                                        __func__);
+                                                }
+                                                else
+                                                {
+                                                    rsrc->wildcard = NO_WILDCARD;
+                                                }
                                             }
 
                                             // "rt"
@@ -1748,6 +1779,36 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
                                                 OIC_LOG_V(DEBUG, TAG, "%s found rel = %s.", __func__, rsrc->rel);
                                             }
 
+                                            // "wc"
+                                            if (0 == strcmp(OIC_JSON_WC_NAME, rMapName))
+                                            {
+                                                char *wc = NULL;
+                                                cborFindResult = cbor_value_dup_text_string(&rMap, &wc, &tempLen, NULL);
+                                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding wc Value.");
+                                                OIC_LOG_V(DEBUG, TAG, "%s found wc = %s.", __func__, wc);
+                                                if (0 == strcmp(OIC_JSON_WC_ASTERISK_NAME, wc))
+                                                {
+                                                    rsrc->wildcard = ALL_RESOURCES;
+                                                    OIC_LOG_V(DEBUG, TAG, "%s set wildcard = ALL_RESOURCES.", __func__);
+                                                }
+                                                else if (0 == strcmp(OIC_JSON_WC_PLUS_NAME, wc))
+                                                {
+                                                    rsrc->wildcard = ALL_DISCOVERABLE;
+                                                    OIC_LOG_V(DEBUG, TAG, "%s set wildcard = ALL_DISCOVERABLE.", __func__);
+                                                }
+                                                else if (0 == strcmp(OIC_JSON_WC_MINUS_NAME, wc))
+                                                {
+                                                    rsrc->wildcard = ALL_NON_DISCOVERABLE;
+                                                    OIC_LOG_V(DEBUG, TAG, "%s set wildcard = ALL_NON_DISCOVERABLE.", __func__);
+                                                }
+                                                else
+                                                {
+                                                    rsrc->wildcard = NO_WILDCARD;
+                                                    OIC_LOG_V(DEBUG, TAG, "%s set wildcard = NO_WILDCARD.", __func__);
+                                                }
+                                                free(wc);
+                                            }
+
                                             if (cbor_value_is_valid(&rMap))
                                             {
                                                 cborFindResult = cbor_value_advance(&rMap);
@@ -1797,7 +1858,7 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
                                         LL_APPEND(ace->validities, validity);
 
                                         CborValue validityMap  = {.parser = NULL};
-                                                //period (string)
+                                        //period (string)
                                         cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap);
                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map.");
 
@@ -1805,7 +1866,7 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
                                         cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &vmLen, NULL);
                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value.");
 
-                                                //recurrence (string array)
+                                        //recurrence (string array)
                                         CborValue recurrenceMap  = {.parser = NULL};
                                         cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap);
                                         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array.");
index 7ea5a2e..f0fb8f2 100644 (file)
@@ -358,14 +358,15 @@ static bool IsAccessWithinValidTime(const OicSecAce_t *ace)
 /**
  * Check whether 'resource' is in the passed ACE.
  *
- * @param resource is the resource being searched.
- * @param ace is the ACE to check.
+ * @param[in] context Context->resourceUri contains the Resource being checked,
+ *                    as well as the discoverability of the Resource.
+ * @param[in] ace The ACE to check.
  *
- * @return true if 'resource' found, otherwise false.
+ * @return true if match found, otherwise false.
  */
-static bool IsResourceInAce(const char *resource, const OicSecAce_t *ace)
+static bool IsResourceInAce(SRMRequestContext_t *context, const OicSecAce_t *ace)
 {
-    if (NULL== ace || NULL == resource)
+    if (NULL == context || NULL == ace)
     {
         return false;
     }
@@ -373,11 +374,29 @@ static bool IsResourceInAce(const char *resource, const OicSecAce_t *ace)
     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)) // TODO IOT-2192
-         {
-             return true;
-         }
+        if (NULL == rsrc->href)
+        {
+            if (NO_WILDCARD != rsrc->wildcard)
+            {
+                if ((ALL_RESOURCES == rsrc->wildcard) ||
+                    (ALL_DISCOVERABLE == rsrc->wildcard &&
+                        DISCOVERABLE_TRUE == context->discoverable) ||
+                    (ALL_NON_DISCOVERABLE == rsrc->wildcard &&
+                        DISCOVERABLE_FALSE == context->discoverable))
+                {
+                    OIC_LOG_V(DEBUG, TAG, "%s: found wc type %d matching resource.",
+                        __func__, rsrc->wildcard);
+                    return true;
+                }
+            }
+        }
+        else if (0 == strcmp(context->resourceUri, rsrc->href) ||
+                 0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
+        {
+            OIC_LOG_V(DEBUG, TAG, "%s: found href %s matching resource.",
+                        __func__, rsrc->href);
+            return true;
+        }
     }
     return false;
 }
@@ -390,7 +409,7 @@ static void ProcessMatchingACE(SRMRequestContext_t *context, const OicSecAce_t *
     // Subject was found, so err changes to Rsrc not found for now.
     context->responseVal = ACCESS_DENIED_RESOURCE_NOT_FOUND;
     OIC_LOG_V(DEBUG, TAG, "%s: Searching for resource...", __func__);
-    if (IsResourceInAce(context->resourceUri, currentAce))
+    if (IsResourceInAce(context, currentAce))
     {
         OIC_LOG_V(INFO, TAG, "%s: found matching resource in ACE.", __func__);
 
index 2da87c8..b95b122 100644 (file)
@@ -137,7 +137,7 @@ void SRMGenerateResponse(SRMRequestContext_t *context)
 }
 
 // Set the value of context->resourceUri, based on the context->requestInfo.
-void SetResourceUriAndType(SRMRequestContext_t *context)
+static void SetResourceUriAndType(SRMRequestContext_t *context)
 {
     char *uri = strstr(context->requestInfo->info.resourceUri, "?");
     size_t position = 0;
@@ -165,11 +165,41 @@ void SetResourceUriAndType(SRMRequestContext_t *context)
     return;
 }
 
-void ClearRequestContext(SRMRequestContext_t *context)
+static void SetDiscoverable(SRMRequestContext_t *context)
 {
+    OCResource *resource;
     if (NULL == context)
     {
+        OIC_LOG_V(ERROR, TAG, "%s: Null context.", __func__);
+        context->discoverable = DISCOVERABLE_NOT_KNOWN;
+    }
+    else if (NULL == context->resourceUri)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: Null resourceUri.", __func__);
+        context->discoverable = DISCOVERABLE_NOT_KNOWN;
+    }
+    else
+    {
+        resource = FindResourceByUri(context->resourceUri);
+        if (OC_DISCOVERABLE == (resource->resourceProperties & OC_DISCOVERABLE))
+        {
+            context->discoverable = DISCOVERABLE_TRUE;
+            OIC_LOG_V(DEBUG, TAG, "%s: resource %s is OC_DISCOVERABLE.",
+                __func__, context->resourceUri);
+        }
+        else
+        {
+            context->discoverable = DISCOVERABLE_FALSE;
+            OIC_LOG_V(DEBUG, TAG, "%s: resource %s is NOT OC_DISCOVERABLE.",
+                __func__, context->resourceUri);
+        }
+    }
+}
 
+static void ClearRequestContext(SRMRequestContext_t *context)
+{
+    if (NULL == context)
+    {
         OIC_LOG(ERROR, TAG, "Null context.");
     }
     else
@@ -185,6 +215,7 @@ void ClearRequestContext(SRMRequestContext_t *context)
         context->requestInfo = NULL;
         context->secureChannel = false;
         context->slowResponseSent = false;
+        context->discoverable = DISCOVERABLE_NOT_KNOWN;
         context->subjectIdType = SUBJECT_ID_TYPE_ERROR;
         memset(&context->subjectUuid, 0, sizeof(context->subjectUuid));
 #ifdef MULTIPLE_OWNER
@@ -280,6 +311,9 @@ void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requ
     // Set resource URI and type.
     SetResourceUriAndType(ctx);
 
+    // Set discoverable enum.
+    SetDiscoverable(ctx);
+
     // Initialize responseInfo.
     memcpy(&(ctx->responseInfo.info), &(requestInfo->info),
         sizeof(ctx->responseInfo.info));
index c7cb535..972dec1 100644 (file)
@@ -475,7 +475,6 @@ OicSecAcl_t* JSONToAclBin(OicSecAclVersion_t *aclVersion, const char * jsonStr)
                     }
                     VERIFY_SUCCESS(TAG, ace->subjectType == OicSecAceConntypeSubject, ERROR);
                 }
-                // */  RESUME HERE
             }
             // Resources -- Mandatory
             jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_RESOURCES_NAME);
@@ -503,15 +502,25 @@ OicSecAcl_t* JSONToAclBin(OicSecAclVersion_t *aclVersion, const char * jsonStr)
 
                 //href
                 cJSON *jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_HREF_NAME);
-                VERIFY_NOT_NULL(TAG, jsonRsrcObj, ERROR);
-                VERIFY_SUCCESS(TAG, cJSON_String == jsonRsrcObj->type, ERROR);
-
-                rsrc->href = OICStrdup(jsonRsrcObj->valuestring);
-                VERIFY_NOT_NULL(TAG, (rsrc->href), ERROR);
+                if (NULL != jsonRsrcObj)
+                {
+                    VERIFY_SUCCESS(TAG, cJSON_String == jsonRsrcObj->type, ERROR);
+                    rsrc->href = OICStrdup(jsonRsrcObj->valuestring);
+                    VERIFY_NOT_NULL(TAG, (rsrc->href), ERROR);
+                    rsrc->wildcard = NO_WILDCARD; // normally if href != NULL, then no wc
+                    if (0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
+                    {
+                        free(rsrc->href);
+                        rsrc->href = NULL;
+                        rsrc->wildcard = ALL_RESOURCES;
+                        OIC_LOG_V(DEBUG, TAG, "%s: replaced \"*\" href with wildcard = ALL_RESOURCES.",
+                            __func__);
+                    }
+                }
 
                 //rel
                 jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_REL_NAME);
-                if(jsonRsrcObj)
+                if (NULL != jsonRsrcObj)
                 {
                     rsrc->rel = OICStrdup(jsonRsrcObj->valuestring);
                     VERIFY_NOT_NULL(TAG, (rsrc->rel), ERROR);
@@ -519,7 +528,7 @@ OicSecAcl_t* JSONToAclBin(OicSecAclVersion_t *aclVersion, const char * jsonStr)
 
                 //rt
                 jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_RT_NAME);
-                if(jsonRsrcObj && cJSON_Array == jsonRsrcObj->type)
+                if ((NULL != jsonRsrcObj) && (cJSON_Array == jsonRsrcObj->type))
                 {
                     rsrc->typeLen = cJSON_GetArraySize(jsonRsrcObj);
                     VERIFY_SUCCESS(TAG, (0 < rsrc->typeLen), ERROR);
@@ -544,7 +553,7 @@ OicSecAcl_t* JSONToAclBin(OicSecAclVersion_t *aclVersion, const char * jsonStr)
 
                 //if
                 jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_IF_NAME);
-                if(jsonRsrcObj && cJSON_Array == jsonRsrcObj->type)
+                if((NULL != jsonRsrcObj) && (cJSON_Array == jsonRsrcObj->type))
                 {
                     rsrc->interfaceLen = cJSON_GetArraySize(jsonRsrcObj);
                     VERIFY_SUCCESS(TAG, (0 < rsrc->interfaceLen), ERROR);
@@ -567,6 +576,32 @@ OicSecAcl_t* JSONToAclBin(OicSecAclVersion_t *aclVersion, const char * jsonStr)
                     }
                 }
 
+                //wc
+                jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_WC_NAME);
+                if (NULL != jsonRsrcObj)
+                {
+                    char *wc = NULL;
+                    VERIFY_SUCCESS(TAG, cJSON_String == jsonRsrcObj->type, ERROR);
+                    wc = OICStrdup(jsonRsrcObj->valuestring);
+                    VERIFY_NOT_NULL(TAG, wc, ERROR);
+                    if (0 == strcmp(OIC_JSON_WC_ASTERISK_NAME, wc))
+                    {
+                        rsrc->wildcard = ALL_RESOURCES;
+                    }
+                    else if (0 == strcmp(OIC_JSON_WC_PLUS_NAME, wc))
+                    {
+                        rsrc->wildcard = ALL_DISCOVERABLE;
+                    }
+                    else if (0 == strcmp(OIC_JSON_WC_MINUS_NAME, wc))
+                    {
+                        rsrc->wildcard = ALL_NON_DISCOVERABLE;
+                    }
+                    else
+                    {
+                        rsrc->wildcard = NO_WILDCARD;
+                    }
+                    OICFree(wc);
+                }
                 LL_APPEND(ace->resources, rsrc);
             }