replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / cloud / cloudWrapper.c
index a94713e..7702c3d 100644 (file)
@@ -1,7 +1,29 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
 #include "logger.h"
 #include "occloudprovisioning.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#include "srmutility.h"
+#include "aclresource.h"
+#include "utlist.h"
 
 #include "utils.h"
 
 //in case of optional parameters absence should be sent NULL
 #define OPTIONAL(str) (str[0] ? str : NULL)
 
+/**
+ * Skip special characters from stdin
+ * */
+static void skipSpecialCharacters()
+{
+    for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                // '0x20<=code' is character region
+}
+
 static bool readOptional(const char* description)
 {
     if (NULL == description)
@@ -36,12 +67,16 @@ static bool readOptional(const char* description)
     }
 
     printf("Do you want to Enter %s (y/n):\n", description);
-    char choice = 0;
+    char temp, choice = 0;
 
     while(1)
     {
-        scanf("%c", &choice);
-        getchar();
+        for(int ret = 0; 1 != ret; )
+        {
+            ret = scanf("%c", &temp);
+            skipSpecialCharacters();
+        }
+        choice = temp;
 
         switch (choice)
         {
@@ -55,11 +90,24 @@ static bool readOptional(const char* description)
 
 void readString(char* item, int length, const char* description, const char* example)
 {
+    char *temp = (char*)OICCalloc(length, sizeof(char));
+    if (NULL == temp)
+    {
+        OIC_LOG(INFO, TAG, "temp is NULL");
+        return;
+    }
+
     printf("Enter %s (f.e. %s):\n", description, example);
     char template[8] = { 0 };
     snprintf(template, sizeof(template), "%%%ds", length - 1);
-    scanf(template, item);
-    getchar();
+
+    for(int ret = 0; 1 != ret; )
+    {
+        ret = scanf(template, temp);
+        skipSpecialCharacters();
+    }
+    strncpy(item, temp, length);
+    OICFree(temp);
 }
 
 /**
@@ -80,9 +128,16 @@ static void readOptionalString(char* item, int length, const char* description,
 
 void readInteger(int* item, const char* description, const char* example)
 {
+    int temp;
+
     printf("Enter %s (f.e. %s):\n", description, example);
-    scanf("%d", item);
-    getchar();
+
+    for(int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%d", &temp);
+        skipSpecialCharacters();
+    }
+    *item = temp;
 }
 
 /**
@@ -158,19 +213,63 @@ static void readOptionalStringArray(stringArray_t *list, int length, const char*
     }
 }
 
-/**
- * Copies whole binary file to crl variable
- *
- * @param[in] list           array of strings structure
- * @param[out] crl           byte array to fill
- * @return                   negative error code
- * */
-static int ReadFile(const char *name, OCByteString *crl)
+void printStringArray(stringArray_t *list)
+{
+    if (NULL == list)
+    {
+        OIC_LOG(INFO, TAG, "Received NULL list");
+        return;
+    }
+
+    OIC_LOG_V(INFO, TAG, "List contains %zu items", list->length);
+
+    for (size_t i = 0; i < list->length; i++)
+    {
+        OIC_LOG_V(INFO, TAG, "item[%zu] = %s", i, list->array[i]);
+    }
+}
+
+void printInviteResponse(inviteResponse_t *in)
+{
+    if (NULL == in)
+    {
+        OIC_LOG(INFO, TAG, "Received NULL invitation response");
+        return;
+    }
+
+    OIC_LOG(INFO, TAG, "Received next invite gid list:");
+    printStringArray(&in->invite.gidlist);
+
+    OIC_LOG(INFO, TAG, "Received next invite mid list:");
+    printStringArray(&in->invite.midlist);
+
+    OIC_LOG(INFO, TAG, "Received next invited gid list:");
+    printStringArray(&in->invited.gidlist);
+
+    OIC_LOG(INFO, TAG, "Received next invited mid list:");
+    printStringArray(&in->invited.midlist);
+}
+
+void clearInviteResponse(inviteResponse_t *in)
+{
+    if (NULL == in)
+    {
+        return;
+    }
+
+    clearStringArray(&in->invite.gidlist);
+    clearStringArray(&in->invite.midlist);
+
+    clearStringArray(&in->invited.gidlist);
+    clearStringArray(&in->invited.midlist);
+}
+
+bool readFile(const char *name, OCByteString *out)
 {
     FILE *file = NULL;
     int length = 0;
     uint8_t *buffer = NULL;
-    int result = 1;
+    bool result = false;
 
     //Open file
     file = fopen(name, "rb");
@@ -181,8 +280,7 @@ static int ReadFile(const char *name, OCByteString *crl)
     }
 
     //Get file length
-    result = fseek(file, 0, SEEK_END);
-    if (result)
+    if (fseek(file, 0, SEEK_END))
     {
         OIC_LOG(ERROR, TAG, "Failed to SEEK_END");
         goto exit;
@@ -195,8 +293,7 @@ static int ReadFile(const char *name, OCByteString *crl)
         goto exit;
     }
 
-    result = fseek(file, 0, SEEK_SET);
-    if (result)
+    if (fseek(file, 0, SEEK_SET))
     {
         OIC_LOG(ERROR, TAG, "Failed to SEEK_SET");
         goto exit;
@@ -211,20 +308,58 @@ static int ReadFile(const char *name, OCByteString *crl)
     }
 
     //Read file contents into buffer
-    size_t realLen = fread(buffer, length, 1, file);
-    if (realLen != (size_t)length)
+    size_t count = 1;
+    size_t realCount = fread(buffer, length, count, file);
+    if (realCount != count)
     {
-        OIC_LOG_V(ERROR, TAG, "Length mismatch: read %zu instead of %d bytes", realLen, length);
+        OIC_LOG_V(ERROR, TAG, "Read %d bytes %zu times instead of %zu", length, realCount, count);
         goto exit;
     }
 
-    crl->bytes = buffer;
-    crl->len   = length;
+    out->bytes = buffer;
+    out->len   = length;
 
-    result = 0;
+    result = true;
 exit:
     fclose(file);
-    return 0;
+    return result;
+}
+
+/**
+ * Frees particular cloudAce object
+ *
+ * @param[in] ace   ace object to free
+ * */
+static void freeCloudAce(cloudAce_t *ace)
+{
+    OICFree(ace->aceId);
+
+    //Clean Resources
+    OicSecRsrc_t* rsrc = NULL;
+    OicSecRsrc_t* tmpRsrc = NULL;
+    LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
+    {
+        LL_DELETE(ace->resources, rsrc);
+        FreeRsrc(rsrc);
+    }
+
+    OICFree(ace);
+}
+
+/**
+ * Deletes cloudAce list
+ *
+ * @param[in] ace   aces list to delete
+ * */
+static void deleteCloudAceList(cloudAce_t *aces)
+{
+    cloudAce_t *ace = NULL;
+    cloudAce_t *tmpAce = NULL;
+    LL_FOREACH_SAFE(aces, ace, tmpAce)
+    {
+        LL_DELETE(aces, ace);
+        freeCloudAce(ace);
+    }
 }
 
 OCStackResult OCWrapperCertificateIssueRequest(const OCDevAddr *endPoint, OCCloudResponseCB callback)
@@ -255,7 +390,7 @@ OCStackResult OCWrapperPostCRL(const OCDevAddr *endPoint, OCCloudResponseCB call
         readString(filename, sizeof(filename),
                    "filename from which binary Crl in DER format will be read", "crl");
 
-        if (ReadFile(filename, &crlData))
+        if (!readFile(filename, &crlData))
         {
             printf("Can't read crl from file %s\n", filename);
             goto exit;
@@ -314,55 +449,54 @@ OCStackResult OCWrapperAclIndividualGetInfo(const OCDevAddr *endPoint, OCCloudRe
 OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloudResponseCB callback)
 {
     OCStackResult result = OC_STACK_NO_MEMORY;
-    int i = 0, j = 0;
 
     char aclid[MAX_ID_LENGTH] = { 0 };
-    readString(aclid, sizeof(aclid), "ace id", ACL_ID_EXAMPLE);
+    readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
 
     int acllist_count = 0;
     readInteger(&acllist_count, "acl list count", "1");
 
-    cloudAce_t *aces = OICCalloc(acllist_count, sizeof(cloudAce_t));
-    if (!aces)
-    {
-        OIC_LOG(ERROR, TAG, "Can't allocate memory for aces");
-        goto exit;
-    }
+    cloudAce_t *aces = NULL;
 
-    for (i = 0; i < acllist_count; i++)
+    for (int i = 0; i < acllist_count; i++)
     {
-        cloudAce_t *ace = &aces[i];
-        if (i != acllist_count - 1) ace->next = &aces[i + 1];
+        cloudAce_t *ace = OICCalloc(1, sizeof(cloudAce_t));
+        if (!ace)
+        {
+            OIC_LOG(ERROR, TAG, "Can't allocate memory for ace");
+            goto exit;
+        }
+        LL_APPEND(aces, ace);
 
         char aceid[MAX_ID_LENGTH] = { 0 };
         char subjectuuid[MAX_ID_LENGTH] = { 0 };
         int stype = 0;
         int permission = 0;
 
-        readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE);
-        readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE);
+        do
+        {
+            readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE);
+        } while (OC_STACK_OK != ConvertStrToUuid(subjectuuid, &ace->subjectuuid));
+
         readInteger(&stype, "subject type", "0 – Device, 1 – User, 2 - Group");
         readInteger(&permission, "permission", "6");
 
         ace->aceId = OICStrdup(aceid);
         ace->stype = stype;
         ace->permission = permission;
-        memcpy(&ace->subjectuuid, subjectuuid, sizeof(OicUuid_t));
 
         int reslist_count = 0;
         readInteger(&reslist_count, "resources list count", "1");
 
-        ace->resources = OICCalloc(reslist_count, sizeof(OicSecRsrc_t));
-        if (!ace->resources)
-        {
-            OIC_LOG(ERROR, TAG, "Can't allocate memory for resources");
-            goto exit;
-        }
-
-        for (j = 0; j < reslist_count; j++)
+        for (int i = 0; i < reslist_count; i++)
         {
-            OicSecRsrc_t *res = &ace->resources[j];
-            if (j != reslist_count - 1) res->next = &ace->resources[j + 1];
+            OicSecRsrc_t *res = OICCalloc(1, sizeof(OicSecRsrc_t));
+            if (!res)
+            {
+                OIC_LOG(ERROR, TAG, "Can't allocate memory for res");
+                goto exit;
+            }
+            LL_APPEND(ace->resources, res);
 
             char href[32] = { 0 };
             readString(href, sizeof(href), "href", RESOURCE_URI_EXAMPLE);
@@ -383,30 +517,73 @@ OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloud
 
     result = OCCloudAclIndividualUpdateAce(NULL, aclid, aces, endPoint, callback);
 exit:
-    if (aces)
+    deleteCloudAceList(aces);
+    return result;
+}
+
+OCStackResult OCWrapperAclIndividualUpdate(const OCDevAddr *endPoint, OCCloudResponseCB callback)
+{
+    OCStackResult result = OC_STACK_NO_MEMORY;
+
+    char aclid[MAX_ID_LENGTH] = { 0 };
+    readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
+
+    cloudAce_t *ace = OICCalloc(1, sizeof(cloudAce_t));
+    if (!ace)
     {
-        for (int k = 0; k < i; k++)
-        {
-            cloudAce_t *ace = &aces[k];
-            OICFree(ace->aceId);
+        OIC_LOG(ERROR, TAG, "Can't allocate memory for ace");
+        goto exit;
+    }
 
-            if (ace->resources)
-            {
-                for (int l = 0; l < j; l++)
-                {
-                    OicSecRsrc_t *res = &ace->resources[l];
-                    OICFree(res->href);
+    char aceid[MAX_ID_LENGTH] = { 0 };
+    char subjectuuid[MAX_ID_LENGTH] = { 0 };
+    int stype = 0;
+    int permission = 0;
 
-                    stringArray_t rt = {.array = res->types, .length = res->typeLen};
-                    clearStringArray(&rt);
+    readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE);
+    do
+    {
+        readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE);
+    } while (OC_STACK_OK != ConvertStrToUuid(subjectuuid, &ace->subjectuuid));
 
-                    stringArray_t _if = {.array = res->interfaces, .length = res->interfaceLen};
-                    clearStringArray(&_if);
-                }
-            }
+    readInteger(&stype, "subject type", "0 – Device, 1 – User, 2 - Group");
+    readInteger(&permission, "permission", "6");
 
+    ace->stype = stype;
+    ace->permission = permission;
+
+    int reslist_count = 0;
+    readInteger(&reslist_count, "resources list count", "1");
+
+    for (int i = 0; i < reslist_count; i++)
+    {
+        OicSecRsrc_t *res = OICCalloc(1, sizeof(OicSecRsrc_t));
+        if (!res)
+        {
+            OIC_LOG(ERROR, TAG, "Can't allocate memory for res");
+            goto exit;
         }
+        LL_APPEND(ace->resources, res);
+
+        char href[32] = { 0 };
+        readString(href, sizeof(href), "href", RESOURCE_URI_EXAMPLE);
+
+        stringArray_t rt = {0, 0};
+        readStringArray(&rt, MAX_ID_LENGTH, "resource type", RESOURCE_TYPE_EXAMPLE);
+
+        stringArray_t _if = {0, 0};
+        readStringArray(&_if, MAX_ID_LENGTH, "interface", INTERFACE_EXAMPLE);
+
+        res->href = OICStrdup(href);
+        res->types = rt.array;
+        res->typeLen = rt.length;
+        res->interfaces = _if.array;
+        res->interfaceLen = _if.length;
     }
+
+
+    result = OCCloudAclIndividualUpdate(NULL, aclid,aceid, ace, endPoint, callback);
+exit:
     return result;
 }
 
@@ -419,6 +596,17 @@ OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudRes
     return OCCloudAclIndividualDelete(NULL, aclid, endPoint, callback);
 }
 
+OCStackResult OCWrapperAclIndividualDeleteAce(const OCDevAddr *endPoint, OCCloudResponseCB callback)
+{
+    char aclid[MAX_ID_LENGTH] = { 0 };
+    char aceid[MAX_ID_LENGTH] = { 0 };
+
+    readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
+    readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE);
+
+    return OCCloudAclIndividualDeleteAce(NULL, aclid, aceid, endPoint, callback);
+}
+
 OCStackResult OCWrapperAclCreateGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
 {
     char gtype[16] = { 0 };