Modify GET request handler for /oic/sec/acl
authorjs126.lee <js126.lee@samsung.com>
Tue, 14 Jun 2016 05:40:31 +0000 (14:40 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Wed, 22 Jun 2016 05:25:35 +0000 (05:25 +0000)
Issue: If 'subject' field is not included in REST request,
       a error occur on HandleACLGetRequest.
       This implementation does not meet the spec, and causes the failure with CTT.

Resolution: A server responds for GET 'oic/sec/acl', even if 'subject' field
            is not included in REST request.

Patch 1: Fixed this issue, and adding GetACL API for debugging only.
Patch 2: Rebase it on the latest master branch

Change-Id: Icb3869fee6039a076ee90146ae94eb527a88865c
Signed-off-by: js126.lee <js126.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/8633
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Chul Lee <chuls.lee@samsung.com>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
resource/csdk/security/provisioning/include/internal/secureresourceprovider.h
resource/csdk/security/provisioning/include/ocprovisioningmanager.h
resource/csdk/security/provisioning/sample/provisioningclient.c
resource/csdk/security/provisioning/src/ocprovisioningmanager.c
resource/csdk/security/provisioning/src/secureresourceprovider.c
resource/csdk/security/src/aclresource.c

index e2117a7..fe4e546 100644 (file)
@@ -53,6 +53,17 @@ OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceI
 OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
         OCProvisionResultCB resultCallback);
 
+/**
+ * API to request ACL information to resource.
+ *
+ * @param[in] selectedDeviceInfo Selected target device.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ *            provisioning request recieves a response from resource server.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+        OCProvisionResultCB resultCallback);
+
 #ifdef __WITH_X509__
 /**
  * API to send CRL information to resource.
index cdd676e..155513e 100644 (file)
@@ -118,17 +118,29 @@ OCStackResult OCProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceIn
 \r
 /**\r
  * this function requests CRED information to resource.\r
- *
- * @param[in] ctx Application context would be returned in result callback.
+ *\r
+ * @param[in] ctx Application context would be returned in result callback.\r
  * @param[in] selectedDeviceInfo Selected target device.\r
- * @param[in] resultCallback callback provided by API user, callback will be called when provisioning
-              request recieves a response from resource server.
- * @return  OC_STACK_OK in case of success and other value otherwise.
- */
+ * @param[in] resultCallback callback provided by API user, callback will be called when provisioning\r
+              request recieves a response from resource server.\r
+ * @return  OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
 OCStackResult OCGetCredResource(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,\r
                              OCProvisionResultCB resultCallback);\r
 \r
 /**\r
+ * this function requests ACL information to resource.\r
+ *\r
+ * @param[in] ctx Application context would be returned in result callback.\r
+ * @param[in] selectedDeviceInfo Selected target device.\r
+ * @param[in] resultCallback callback provided by API user, callback will be called when provisioning\r
+              request recieves a response from resource server.\r
+ * @return  OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCGetACLResource(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,\r
+                             OCProvisionResultCB resultCallback);\r
+\r
+/**\r
  * this function sends Direct-Pairing Configuration to a device.\r
  *\r
  * @param[in] ctx Application context would be returned in result callback.\r
index eb20586..3807ef8 100644 (file)
@@ -51,6 +51,7 @@ extern "C"
 #define _40_UNLINK_PAIR_DEVS_   40
 #define _50_REMOVE_SELEC_DEV_   50
 #define _60_GET_CRED_  60
+#define _61_GET_ACL_            61
 #define _99_EXIT_PRVN_CLT_      99
 
 #define ACL_RESRC_MAX_NUM   16
@@ -164,6 +165,20 @@ static void getCredCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasE
     g_doneCB = true;
 }
 
+static void getAclCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
+{
+    if(!hasError)
+    {
+        OIC_LOG_V(INFO, TAG, "getAclCB SUCCEEDED - ctx: %s", (char*) ctx);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "getAclCB FAILED - ctx: %s", (char*) ctx);
+        printResultList((const OCProvisionResult_t*) arr, nOfRes);
+    }
+    g_doneCB = true;
+}
+
 static void provisionDPCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
 {
     if(!hasError)
@@ -851,6 +866,66 @@ PVACL_ERROR:
     return -1;
 }
 
+static int getAcl(void)
+{
+    // check |own_list| for checking selected link status on PRVN DB
+    if(!g_own_list || 1>g_own_cnt)
+    {
+        printf("   > Owned Device List, to Check Linked Status on PRVN DB, is Empty\n");
+        printf("   > Please Register Unowned Devices first, with [20] Menu\n");
+        return 0;  // normal case
+    }
+
+    // select device for checking selected link status on PRVN DB
+    int dev_num = 0;
+    for( ; ; )
+    {
+        printf("   > Enter Device Number, for Checking Linked Status on PRVN DB: ");
+        for(int ret=0; 1!=ret; )
+        {
+            ret = scanf("%d", &dev_num);
+            for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                        // '0x20<=code' is character region
+        }
+        if(0<dev_num && g_own_cnt>=dev_num)
+        {
+            break;
+        }
+        printf("     Entered Wrong Number. Please Enter Again\n");
+    }
+
+    // call |getDevInst| API actually
+    // calling this API with callback actually acts like blocking
+    // for error checking, the return value saved and printed
+    g_doneCB = false;
+    OCProvisionDev_t* dev = getDevInst((const OCProvisionDev_t*) g_own_list, dev_num);
+    if(!dev)
+    {
+        OIC_LOG(ERROR, TAG, "getDevInst: device instance empty");
+        goto PVACL_ERROR;
+    }
+    OCStackResult rst = OCGetACLResource((void*) g_ctx, dev, getAclCB);
+    if(OC_STACK_OK != rst)
+    {
+        OIC_LOG_V(ERROR, TAG, "OCGetACLResource API error: %d", rst);
+
+        goto PVACL_ERROR;
+    }
+    if(waitCallbackRet())  // input |g_doneCB| flag implicitly
+    {
+        OIC_LOG(ERROR, TAG, "OCGetACLResource callback error");
+        goto PVACL_ERROR;
+    }
+
+    // display the result of get credential
+    printf("   > Get ACL SUCCEEDED\n");
+
+    return 0;
+
+PVACL_ERROR:
+    return -1;
+}
+
 static int unlinkPairwise(void)
 {
     // check |own_list| for unlinking pairwise devices
@@ -1350,7 +1425,8 @@ static void printMenu(void)
     printf("** 50. Remove the Selected Device\n\n");
 
     printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
-    printf("** 60. Get the Credential resources of the Selected Device\n\n");
+    printf("** 60. Get the Credential resources of the Selected Device\n");
+    printf("** 61. Get the ACL resources of the Selected Device\n\n");
 
     printf("** [F] EXIT PROVISIONING CLIENT\n");
     printf("** 99. Exit Provisionong Client\n\n");
@@ -1476,6 +1552,12 @@ int main()
                 OIC_LOG(ERROR, TAG, "_60_GET_CRED_: error");
             }
             break;
+        case _61_GET_ACL_:
+            if(getAcl())
+            {
+                OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
+            }
+            break;
         case _99_EXIT_PRVN_CLT_:
             goto PMCLT_ERROR;
         default:
index 583b116..ad8133d 100644 (file)
@@ -178,6 +178,21 @@ OCStackResult OCGetCredResource(void* ctx, const OCProvisionDev_t *selectedDevic
 }
 
 /**
+ * this function requests ACL information to resource.
+ *
+ * @param[in] ctx Application context would be returned in result callback.
+ * @param[in] selectedDeviceInfo Selected target device.
+ * @param[in] resultCallback callback provided by API user, callback will be called when provisioning
+              request recieves a response from resource server.
+ * @return  OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult OCGetACLResource(void* ctx, const OCProvisionDev_t *selectedDeviceInfo,
+                             OCProvisionResultCB resultCallback)
+{
+    return SRPGetACLResource(ctx, selectedDeviceInfo, resultCallback);
+}
+
+/**
  * function to provision credential to devices.
  *
  * @param[in] ctx Application context would be returned in result callback.
index a5e11e7..1a2a65a 100644 (file)
@@ -1844,4 +1844,123 @@ OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDevi
     return OC_STACK_OK;
 }
 
+/**
+ * Internal Function to store results in result array during GetACLResourceCB.
+ */
+static void registerResultForGetACLResourceCB(GetSecData_t *GetSecData,
+                                             OCStackResult stackresult)
+{
+   OIC_LOG_V(INFO, TAG, "Inside registerResultForGetACLResourceCB "
+           "GetSecData->numOfResults is %d\n", GetSecData->numOfResults);
+   memcpy(GetSecData->resArr[(GetSecData->numOfResults)].deviceId.id,
+          GetSecData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
+   GetSecData->resArr[(GetSecData->numOfResults)].res = stackresult;
+   ++(GetSecData->numOfResults);
+}
+
+/**
+ * Callback handler of SRPGetACLResource.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult SRPGetACLResourceCB(void *ctx, OCDoHandle UNUSED,
+                                                  OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(INFO, TAG, "Inside SRPGetACLResourceCB.");
+    (void)UNUSED;
+    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    GetSecData_t *GetSecData = (GetSecData_t*)ctx;
+    OCProvisionResultCB resultCallback = GetSecData->resultCallback;
+
+    if (clientResponse)
+    {
+        if(OC_STACK_OK == clientResponse->result)
+        {
+            uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
+            size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
+
+            OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
+
+            registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK);
+            ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
+                                                    GetSecData->resArr,
+                                                    false);
+             OICFree(GetSecData->resArr);
+             OICFree(GetSecData);
+
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+    }
+    registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK);
+    ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
+                                            GetSecData->resArr,
+                                            false);
+    OIC_LOG_V(ERROR, TAG, "SRPGetACLResourceCB received Null clientResponse");
+    OICFree(GetSecData->resArr);
+    OICFree(GetSecData);
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
 
+OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+        OCProvisionResultCB resultCallback)
+{
+    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    if(!PMGenerateQuery(true,
+                        selectedDeviceInfo->endpoint.addr,
+                        selectedDeviceInfo->securePort,
+                        selectedDeviceInfo->connType,
+                        query, sizeof(query), OIC_RSRC_ACL_URI))
+    {
+        OIC_LOG(ERROR, TAG, "SRPGetACLResource : Failed to generate query");
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
+    cbData.cb = &SRPGetACLResourceCB;
+    GetSecData_t* GetSecData = (GetSecData_t*)OICCalloc(1, sizeof(GetSecData_t));
+    if (NULL == GetSecData)
+    {
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    GetSecData->deviceInfo = selectedDeviceInfo;
+    GetSecData->resultCallback = resultCallback;
+    GetSecData->numOfResults=0;
+    GetSecData->ctx = ctx;
+
+    int noOfRiCalls = 1;
+    GetSecData->resArr = (OCProvisionResult_t*)OICCalloc(noOfRiCalls, sizeof(OCProvisionResult_t));
+    if (NULL == GetSecData->resArr)
+    {
+        OICFree(GetSecData);
+        OIC_LOG(ERROR, TAG, "Unable to allocate memory");
+        return OC_STACK_NO_MEMORY;
+    }
+    cbData.context = (void *)GetSecData;
+    cbData.cd = NULL;
+    OCMethod method = OC_REST_GET;
+    OCDoHandle handle = NULL;
+    OIC_LOG(DEBUG, TAG, "Sending Get ACL to resource server");
+    OCStackResult ret = OCDoResource(&handle, method, query, NULL, NULL,
+            selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+        OICFree(GetSecData->resArr);
+        OICFree(GetSecData);
+    }
+    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    OIC_LOG(DEBUG, TAG, "OUT SRPGetACLResource");
+
+    return OC_STACK_OK;
+}
index 04d1108..381c82f 100644 (file)
@@ -889,20 +889,20 @@ static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *e
     size_t size = 0;
     OCEntityHandlerResult ehRet;
 
-    // Process the REST querystring parameters
-    if (ehRequest->query)
+    OicUuid_t subject = {.id= { 0 } };
+
+    // In case, 'subject' field is included in REST request.
+    if (ehRequest->query && GetSubjectFromQueryString(ehRequest->query, &subject))
     {
+        OIC_LOG(DEBUG,TAG,"'subject' field is inculded in REST request.");
         OIC_LOG(DEBUG, TAG, "HandleACLGetRequest processing query");
 
-        OicUuid_t subject = {.id= { 0 } };
         char resource[MAX_URI_LENGTH] = { 0 };
 
         OicSecAcl_t *savePtr = NULL;
         const OicSecAcl_t *currentAce = NULL;
 
         // 'Subject' field is MUST for processing a querystring in REST request.
-        VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR);
-
         GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
 
         /*
@@ -944,8 +944,10 @@ static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *e
             }
         }
     }
+    // In case, 'subject' field is not included in REST request.
     else
     {
+        OIC_LOG(DEBUG,TAG,"'subject' field is not inculded in REST request.");
         // Convert ACL data into CBOR format for transmission.
         if (OC_STACK_OK != AclToCBORPayload(gAcl, &payload, &size))
         {