1 /* *****************************************************************
3 * Copyright 2017 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * *****************************************************************/
25 #include "oic_malloc.h"
27 #include "psinterface.h"
29 #include "srmresourcestrings.h"
30 #include "security_internals.h"
31 #include "aclresource.h"
33 #include "svrdbeditoracl.h"
35 #define ACL_PEMISN_CNT (5)
36 #define ACE_MAX_ENTITY (256)
38 static OicSecAcl_t *g_acl = NULL;
40 typedef enum AclModifyType
45 typedef enum AceModifyType
51 ACE_EDIT_PERMISSION = 5
65 OicSecAcl_t *tmpACL = NULL;
66 uint8_t *secPayload = NULL;
67 size_t payloadSize = 0;
68 OCStackResult ocResult = OC_STACK_ERROR;
69 ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &secPayload, &payloadSize);
70 if (OC_STACK_OK != ocResult)
72 PRINT_WARN("Failed GetSecureVirtualDatabaseFromPS");
76 tmpACL = CBORPayloadToAcl(secPayload, payloadSize);
79 PRINT_ERR("Failed CBORPayloadToAcl");
92 static void UpdateACL(void)
94 OCStackResult aclResult = OC_STACK_ERROR;
95 uint8_t *aclPayload = NULL;
96 size_t aclPayloadSize = 0;
98 aclResult = AclToCBORPayload(g_acl, &aclPayload, &aclPayloadSize);
99 if (OC_STACK_OK != aclResult)
101 PRINT_ERR("AclToCBORPayload error : %d" , aclResult);
104 aclResult = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, aclPayload, aclPayloadSize);
105 if (OC_STACK_OK != aclResult)
107 PRINT_ERR("UpdateSecureResourceInPS error : %d" , aclResult);
114 static void FreeACE(OicSecAce_t *ace)
118 PRINT_ERR("Invalid parameter");
123 OicSecRsrc_t *rsrc = NULL;
124 OicSecRsrc_t *tmpRsrc = NULL;
125 LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
127 LL_DELETE(ace->resources, rsrc);
131 OicSecValidity_t *validity = NULL;
132 OicSecValidity_t *tmpValidity = NULL;
133 LL_FOREACH_SAFE(ace->validities, validity, tmpValidity)
135 LL_DELETE(ace->validities, validity);
138 OICFree(validity->period);
141 for (size_t i = 0; i < validity->recurrenceLen; i++)
143 OICFree(validity->recurrences[i]);
145 OICFree(validity->recurrences);
150 #ifdef MULTIPLE_OWNER
151 OICFree(ace->eownerID);
156 static void PrintValidity(const OicSecValidity_t *validities)
158 const OicSecValidity_t *validity = NULL;
159 const OicSecValidity_t *tempValidity = NULL;
160 size_t validityCnt = 0;
162 LL_FOREACH_SAFE(validities, validity, tempValidity)
164 PRINT_DATA("Validity #%zu:\n", validityCnt + 1);
165 PRINT_DATA("%10s : %s\n", OIC_JSON_PERIOD_NAME, validity->period);
166 PRINT_DATA("%10s : ", OIC_JSON_RESOURCES_NAME);
167 PrintStringArray((const char **)validity->recurrences, validity->recurrenceLen);
172 static void PrintPermission(uint16_t permission)
174 PRINT_DATA("%d (", permission);
178 PRINT_DATA(" NO PERMISSION");
182 if (permission & PERMISSION_CREATE)
184 PRINT_DATA(" CREATE ");
186 if (permission & PERMISSION_READ)
188 PRINT_DATA(" READ ");
190 if (permission & PERMISSION_WRITE)
192 PRINT_DATA(" WRITE ");
194 if (permission & PERMISSION_DELETE)
196 PRINT_DATA(" DELETE ");
198 if (permission & PERMISSION_NOTIFY)
200 PRINT_DATA(" NOTIFY ");
207 static size_t PrintResourceList(const OicSecRsrc_t *rsrcList)
209 const OicSecRsrc_t *rsrc = NULL;
210 const OicSecRsrc_t *tempRsrc = NULL;
213 LL_FOREACH_SAFE(rsrcList, rsrc, tempRsrc)
215 PRINT_DATA("Resource #%zu:\n", rsrcCnt + 1);
216 PRINT_DATA("%10s : %s\n", OIC_JSON_HREF_NAME, rsrc->href);
217 PRINT_DATA("%10s : %s\n", OIC_JSON_REL_NAME, rsrc->rel);
218 PRINT_DATA("%10s : ", OIC_JSON_RT_NAME);
219 PrintStringArray((const char **)rsrc->types, rsrc->typeLen);
220 PRINT_DATA("%10s : ", OIC_JSON_IF_NAME);
221 PrintStringArray((const char **)rsrc->interfaces, rsrc->interfaceLen);
228 static int PrintAce(const OicSecAce_t *ace)
230 PRINT_PROG("%15s : ", OIC_JSON_SUBJECT_NAME);
231 if (memcmp(&(ace->subjectuuid), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0)
233 PrintString((char *)WILDCARD_SUBJECT_ID.id);
237 PrintUuid(&(ace->subjectuuid));
240 #ifdef MULTIPLE_OWNER
243 PRINT_PROG("%15s : ", OIC_JSON_EOWNERID_NAME);
244 PrintUuid(&(ace->subjectuuid));
249 PRINT_PROG("%15s : ", OIC_JSON_PERMISSION_NAME);
250 PrintPermission(ace->permission);
253 PRINT_PROG("%15s : \n", OIC_JSON_RESOURCES_NAME);
254 PrintResourceList(ace->resources);
257 PrintValidity(ace->validities);
262 size_t PrintAcl(void)
264 OicSecAce_t *ace = NULL;
265 OicSecAce_t *tempAce = NULL;
266 bool isEmptyList = true;
269 PRINT_INFO("\n\n********************* [%-20s] *********************",
273 LL_FOREACH_SAFE(g_acl->aces, ace, tempAce)
275 PRINT_INFO("[ACE #%zu]", ++aceCnt);
276 if (0 != PrintAce(ace))
280 PRINT_PROG("------------------------------------------------------------------\n");
286 PRINT_PROG("ACE is empty.\n");
287 PRINT_PROG("------------------------------------------------------------------\n");
289 PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
290 PrintUuid(&(g_acl->rownerID));
294 PRINT_PROG("ACL is empty.\n");
297 PRINT_INFO("********************* [%-20s] *********************",
303 static int InputSubjectUuid(OicSecAce_t *ace)
307 PRINT_DATA("\tInput the Subject UUID for this access (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
308 ret = InputUuid(&ace->subjectuuid);
311 PRINT_ERR("Failed InputUuid");
317 static int InputResources(OicSecRsrc_t *resources)
323 char **interfaces = NULL;
324 size_t interfaceLen = 0;
326 if (NULL == resources)
328 PRINT_ERR("Invalid parameter");
332 href = InputString("\tInput the resource URI : ");
335 PRINT_ERR("Failed InputString");
340 PRINT_PROG("\tInput the number of resource type for %s (MAX : %d): ", href,
342 typeLen = InputNumber("");
343 if (0 == typeLen || SVR_MAX_ENTITY < typeLen)
345 PRINT_ERR("Invalid number");
349 types = (char **)OICCalloc(typeLen, sizeof(char *));
352 PRINT_ERR("Failed to allocate memory");
357 for (i = 0; i < typeLen; i++)
359 PRINT_PROG("\tInput the resource type name #%zu : ", i + 1);
360 types[i] = InputString("");
361 if (NULL == types[i] )
363 PRINT_ERR("Failed InputString");
365 for (size_t j = 0; j < i; j++)
374 PRINT_PROG("\tInput the number of interface for %s (MAX : %d): ", href, SVR_MAX_ENTITY);
375 interfaceLen = InputNumber("");
376 if (0 == interfaceLen || SVR_MAX_ENTITY < interfaceLen)
378 PRINT_ERR("Invalid number");
380 for (size_t j = 0; j < typeLen; j++)
387 interfaces = (char **)OICCalloc(interfaceLen, sizeof(char *));
388 if (NULL == interfaces)
390 PRINT_ERR("Failed to allocate memory");
392 for (size_t j = 0; j < typeLen; j++)
401 for (i = 0; i < interfaceLen; i++)
403 PRINT_PROG("\tInput the interface name #%zu : ", i + 1);
404 interfaces[i] = InputString("");
405 if (NULL == interfaces[i] )
407 PRINT_ERR("Failed InputString");
409 for (size_t j = 0; j < typeLen; j++)
415 for (size_t j = 0; j < i; j++)
417 OICFree(interfaces[j]);
424 // free before assign
425 OICFree(resources->href);
426 if (0 < resources->typeLen && resources->types)
428 for (i = 0; i < resources->typeLen; i++)
430 OICFree(resources->types[i]);
432 OICFree(resources->types);
434 if (0 < resources->interfaceLen && resources->interfaces)
436 for (i = 0; i < resources->interfaceLen; i++)
438 OICFree(resources->interfaces[i]);
440 OICFree(resources->interfaces);
444 resources->href = href;
445 resources->typeLen = typeLen;
446 resources->types = types;
447 resources->interfaceLen = interfaceLen;
448 resources->interfaces = interfaces;
452 static uint16_t InputAccessPermission(void)
454 uint16_t pmsn = PERMISSION_FULL_CONTROL; // default full permission
455 uint16_t pmsn_msk = PERMISSION_CREATE; // default permission mask
456 const char *ACL_PEMISN[ACL_PEMISN_CNT] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
458 for (int i = 0; i < ACL_PEMISN_CNT; i++)
463 PRINT_NORMAL("\tEnter %s Permission (y/n): ", ACL_PEMISN[i]);
464 for (int ret = 0; 1 != ret; )
466 ret = scanf("%c", &ans);
467 for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
468 // '0x20<=code' is character region
470 if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
472 ans &= ~0x20; // for masking lower case, 'y/n'
475 PRINT_NORMAL("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
477 if ('N' == ans) // masked lower case, 'n'
486 int InputAceData(OicSecAce_t *ace)
489 size_t numOfRsrc = 0;
491 PRINT_PROG("\n\nPlease input the each entity of new ACE.\n");
493 ret = InputSubjectUuid(ace);
496 PRINT_ERR("Failed InputSubjectUuid");
499 PRINT_PROG("\tInput the number of resource for this access : ");
500 numOfRsrc = InputNumber("");
501 if (SVR_MAX_ENTITY < numOfRsrc)
503 PRINT_ERR("Invalid number");
507 for (size_t i = 0; i < numOfRsrc; i++)
509 PRINT_PROG("Please input the resource information for resource #%zu\n", i + 1);
510 OicSecRsrc_t *rsrc = (OicSecRsrc_t *)OICCalloc(1, sizeof(OicSecRsrc_t));
513 PRINT_ERR("Failed to allocate memory");
517 ret = InputResources(rsrc);
520 PRINT_ERR("Failed InputResources");
524 LL_APPEND(ace->resources, rsrc);
527 PRINT_PROG("\tSelect permission for this access.\n");
528 ace->permission = InputAccessPermission();
530 #ifdef MULTIPLE_OWNER
531 // TODO: Input eowner
534 // TODO: Input the validity (T.B.D)
539 static int ModifyAce(OicSecAce_t *ace)
544 size_t sizeOfRsrc = 0;
547 OicSecRsrc_t *rsrc = NULL;
548 OicSecRsrc_t *tmpRsrc = NULL;
550 PRINT_PROG("\n\nPlease input the attribute you want to modify\n");
551 PRINT_DATA("\t%2d. Edit subject\n", ACE_EDIT_SUBJECT);
552 PRINT_DATA("\t%2d. Add resources \n", ACE_ADD_RESOURCE);
553 PRINT_DATA("\t%2d. Remove resources \n", ACE_REMOVE_RESOURCE);
554 PRINT_DATA("\t%2d. Edit resources \n", ACE_EDIT_RESOURCE);
555 PRINT_DATA("\t%2d. Edit permission\n", ACE_EDIT_PERMISSION);
556 PRINT_DATA("\t%2d. Back to the previous\n", BACK);
557 modifyMenu = InputNumber("Select the menu : ");
560 case ACE_EDIT_SUBJECT:
561 ret = InputSubjectUuid(ace);
564 PRINT_ERR("InputSubjectType error");
568 case ACE_ADD_RESOURCE :
569 PRINT_PROG("Please input the resource information for resource to add\n");
570 rsrc = (OicSecRsrc_t *)OICCalloc(1, sizeof(OicSecRsrc_t));
573 PRINT_ERR("Failed to allocate memory");
577 ret = InputResources(rsrc);
580 PRINT_ERR("InputResources error");
584 LL_APPEND(ace->resources, rsrc);
586 case ACE_REMOVE_RESOURCE:
587 sizeOfRsrc = PrintResourceList(ace->resources);
588 rsrcIdx = InputNumber("\tInput the number of resource to remove : ");
589 if (0 == rsrcIdx || sizeOfRsrc < rsrcIdx)
591 PRINT_ERR("Invalid number");
594 LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
596 if (rsrcIdx == ++curIdx)
598 LL_DELETE(ace->resources, rsrc);
604 case ACE_EDIT_RESOURCE:
605 sizeOfRsrc = PrintResourceList(ace->resources);
606 PRINT_PROG("\tInput the number of resource to edit : ");
607 rsrcIdx = InputNumber("");
608 if (0 == rsrcIdx || sizeOfRsrc < rsrcIdx)
610 PRINT_ERR("Invalid number");
613 LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
615 if (rsrcIdx == ++curIdx)
617 PRINT_PROG("Please input the resource information for resource #%zu\n", rsrcIdx );
618 ret = InputResources(rsrc);
621 PRINT_ERR("InputResources error");
628 case ACE_EDIT_PERMISSION:
629 PRINT_PROG("\tSelect permission for this access.\n");
630 ace->permission = InputAccessPermission();
633 PRINT_INFO("Back to the previous menu.");
637 PRINT_ERR("Wrong type Number");
644 static int ModifyAcl(void)
648 OicSecAce_t *ace = NULL;
649 OicSecAce_t *tempAce = NULL;
654 PRINT_PROG("\n\nPlease select the menu you want to modify\n");
655 PRINT_DATA("\t%2d. Modify ACE\n", ACL_MODIFY_ACE);
656 PRINT_DATA("\t%2d. Edit rownerid\n", ACL_EDIT_ROWNERID);
657 modifyMenu = InputNumber("Select the menu : ");
661 numOfAce = PrintAcl();
664 PRINT_ERR("empty ace");
667 aclIdx = InputNumber("\tPlease input the number of ACE : ");
668 if (0 == aclIdx || numOfAce < aclIdx)
670 PRINT_ERR("Wrong number of ACE.");
675 LL_FOREACH_SAFE(g_acl->aces, ace, tempAce)
679 //If found target ACE, modify it.
680 if (aclIdx == ++curIdx)
682 if (0 != ModifyAce(ace))
684 PRINT_ERR("Failed to Moidfy ACE");
687 PRINT_INFO("\n\n[ACE #%zu] Modified", aclIdx);
694 case ACL_EDIT_ROWNERID:
696 "\tInput the ROWNER UUID for this access (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
697 ret = InputUuid(&(g_acl->rownerID));
700 PRINT_ERR("InputUuid error");
705 PRINT_ERR("Wrong type Number");
712 void HandleAclOperation(const SubOperationType_t cmd)
718 g_acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
721 PRINT_ERR("Failed to allocate memory");
725 if (SVR_EDIT_IDX_SIZE <= cmd)
727 PRINT_ERR("Invalid menu for ACL");
737 OicSecAce_t *ace = (OicSecAce_t *)OICCalloc(1, sizeof(OicSecAce_t));
741 PRINT_ERR("Failed to allocate memory");
745 if (0 != InputAceData(ace))
747 PRINT_ERR("Failed to input ACE");
753 LL_APPEND(g_acl->aces, ace);
759 OicSecAce_t *ace = NULL;
760 OicSecAce_t *tempAce = NULL;
764 numOfAce = PrintAcl();
767 PRINT_ERR("empty ace");
771 aclIdx = InputNumber("\tPlease input the number of ACE : ");
773 if (0 == aclIdx || aclIdx > numOfAce)
775 PRINT_ERR("Wrong number of ACE.");
780 LL_FOREACH_SAFE(g_acl->aces, ace, tempAce)
784 //If found target ACE, delete it.
785 if (aclIdx == ++curIdx)
787 LL_DELETE(g_acl->aces, ace);
799 PRINT_ERR("empty acl");
802 if (0 != ModifyAcl())
804 PRINT_ERR("Fail ModifyAcl");