1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
31 #include "ocserverrequest.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
35 #include "ocpayload.h"
37 #include "payload_logging.h"
38 #include "srmresourcestrings.h"
39 #include "aclresource.h"
40 #include "doxmresource.h"
41 #include "resourcemanager.h"
42 #include "srmutility.h"
43 #include "psinterface.h"
45 #include "security_internals.h"
48 #define NUMBER_OF_SEC_PROV_RSCS 4
49 #define NUMBER_OF_DEFAULT_SEC_RSCS 2
50 #define STRING_UUID_SIZE (UUID_LENGTH * 2 + 5)
52 static const uint8_t ACL_MAP_SIZE = 4;
53 static const uint8_t ACL_ACLIST_MAP_SIZE = 1;
54 static const uint8_t ACL_ACES_MAP_SIZE = 3;
55 static const uint8_t ACL_RESOURCE_MAP_SIZE = 3;
58 // CborSize is the default cbor payload size being used.
59 static const uint16_t CBOR_SIZE = 2048;
61 static OicSecAcl_t *gAcl = NULL;
62 static OCResourceHandle gAclHandle = NULL;
65 * This function frees OicSecRsrc_t object's fields and object itself.
67 static void FreeRsrc(OicSecRsrc_t *rsrc)
69 //Clean each member of resource
73 if(0 < rsrc->typeLen && rsrc->types)
75 for(size_t i = 0; i < rsrc->typeLen; i++)
77 OICFree(rsrc->types[i]);
83 if(0 < rsrc->interfaceLen && rsrc->interfaces)
85 for(size_t i = 0; i < rsrc->interfaceLen; i++)
87 OICFree(rsrc->interfaces[i]);
89 OICFree(rsrc->interfaces);
90 rsrc->interfaces = NULL;
97 * This function frees OicSecAcl_t object's fields and object itself.
99 static void FreeACE(OicSecAce_t *ace)
103 OIC_LOG(ERROR, TAG, "Invalid Parameter");
108 OicSecRsrc_t* rsrc = NULL;
109 OicSecRsrc_t* tmpRsrc = NULL;
110 LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
112 LL_DELETE(ace->resources, rsrc);
117 OicSecValidity_t *validity = NULL;
118 OicSecValidity_t *tmpValidity = NULL;
119 LL_FOREACH_SAFE(ace->validities, validity, tmpValidity)
121 LL_DELETE(ace->validities, validity);
124 OICFree(validity->period);
127 for(size_t i = 0; i < validity->recurrenceLen; i++)
129 OICFree(validity->recurrences[i]);
131 OICFree(validity->recurrences);
141 void DeleteACLList(OicSecAcl_t* acl)
145 OicSecAce_t *ace = NULL;
146 OicSecAce_t *tmpAce = NULL;
147 LL_FOREACH_SAFE(acl->aces, ace, tmpAce)
149 LL_DELETE(acl->aces, ace);
157 OicSecAce_t* DuplicateACE(const OicSecAce_t* ace)
159 OicSecAce_t* newAce = NULL;
160 size_t allocateSize = 0;
164 newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
165 VERIFY_NON_NULL(TAG, newAce, ERROR);
168 memcpy(&newAce->subjectuuid, &ace->subjectuuid, sizeof(OicUuid_t));
170 OicSecRsrc_t* rsrc = NULL;
171 LL_FOREACH(ace->resources, rsrc)
173 OicSecRsrc_t* newRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
174 VERIFY_NON_NULL(TAG, newRsrc, ERROR);
175 LL_APPEND(newAce->resources, newRsrc);
178 VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
179 allocateSize = strlen(rsrc->href) + 1;
180 newRsrc->href = (char*)OICMalloc(sizeof(char) * allocateSize);
181 VERIFY_NON_NULL(TAG, newRsrc->href, ERROR);
182 OICStrcpy(newRsrc->href, allocateSize, rsrc->href);
186 allocateSize = strlen(rsrc->rel) + 1;
187 newRsrc->rel = (char*)OICMalloc(sizeof(char) * allocateSize);
188 VERIFY_NON_NULL(TAG, newRsrc->rel, ERROR);
189 OICStrcpy(newRsrc->rel, allocateSize, rsrc->rel);
192 if(rsrc->types && 0 < rsrc->typeLen)
194 newRsrc->typeLen = rsrc->typeLen;
195 newRsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
196 VERIFY_NON_NULL(TAG, (newRsrc->types), ERROR);
197 for(size_t i = 0; i < rsrc->typeLen; i++)
199 newRsrc->types[i] = OICStrdup(rsrc->types[i]);
200 VERIFY_NON_NULL(TAG, (newRsrc->types[i]), ERROR);
204 if(rsrc->interfaces && 0 < rsrc->interfaceLen)
206 newRsrc->interfaceLen = rsrc->interfaceLen;
207 newRsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
208 VERIFY_NON_NULL(TAG, (newRsrc->interfaces), ERROR);
209 for(size_t i = 0; i < rsrc->interfaceLen; i++)
211 newRsrc->interfaces[i] = OICStrdup(rsrc->interfaces[i]);
212 VERIFY_NON_NULL(TAG, (newRsrc->interfaces[i]), ERROR);
218 newAce->permission = ace->permission;
223 OicSecValidity_t* validity = NULL;
224 LL_FOREACH(ace->validities, validity)
226 OicSecValidity_t* newValidity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
227 VERIFY_NON_NULL(TAG, newValidity, ERROR);
228 LL_APPEND(newAce->validities, newValidity);
232 allocateSize = strlen(validity->period) + 1;
233 newValidity->period = (char*)OICMalloc(sizeof(char) * allocateSize);
234 VERIFY_NON_NULL(TAG, newValidity->period, ERROR);
235 OICStrcpy(newValidity->period, allocateSize, validity->period);
238 if(validity->recurrences && 0 < validity->recurrenceLen)
240 newValidity->recurrenceLen = validity->recurrenceLen;
242 newValidity->recurrences = (char**)OICMalloc(sizeof(char*) * validity->recurrenceLen);
243 VERIFY_NON_NULL(TAG, newValidity->recurrences, ERROR);
245 for(size_t i = 0; i < validity->recurrenceLen; i++)
247 allocateSize = strlen(validity->recurrences[i]) + 1;
248 newValidity->recurrences[i] = (char*)OICMalloc(sizeof(char) * allocateSize);
249 VERIFY_NON_NULL(TAG, (newValidity->recurrences[i]), ERROR);
250 OICStrcpy(newValidity->recurrences[i], allocateSize, validity->recurrences[i]);
266 static size_t OicSecAclSize(const OicSecAcl_t *secAcl)
272 OicSecAce_t *ace= (OicSecAce_t *)secAcl->aces;
282 OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, size_t *size)
284 if (NULL == secAcl || NULL == payload || NULL != *payload || NULL == size)
286 return OC_STACK_INVALID_PARAM;
289 OCStackResult ret = OC_STACK_ERROR;
290 CborError cborEncoderResult = CborNoError;
291 OicSecAcl_t *acl = (OicSecAcl_t *)secAcl;
292 OicSecAce_t* ace = NULL;
295 CborEncoder aclListMap;
296 CborEncoder acesArray;
297 uint8_t *outPayload = NULL;
298 size_t cborLen = *size;
307 outPayload = (uint8_t *)OICCalloc(1, cborLen);
308 VERIFY_NON_NULL(TAG, outPayload, ERROR);
309 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
311 // Create ACL Map (aclist, rownerid)
312 cborEncoderResult = cbor_encoder_create_map(&encoder, &aclMap, ACL_MAP_SIZE);
313 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACL Map.");
315 cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ACLIST_NAME,
316 strlen(OIC_JSON_ACLIST_NAME));
317 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding aclist Name Tag.");
319 // Create ACLIST Map (aces)
320 cborEncoderResult = cbor_encoder_create_map(&aclMap, &aclListMap, ACL_ACLIST_MAP_SIZE);
321 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACLIST Map.");
323 cborEncoderResult = cbor_encode_text_string(&aclListMap, OIC_JSON_ACES_NAME,
324 strlen(OIC_JSON_ACES_NAME));
325 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACES Name Tag.");
328 cborEncoderResult = cbor_encoder_create_array(&aclListMap, &acesArray, OicSecAclSize(secAcl));
329 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Array.");
332 LL_FOREACH (acl->aces, ace)
334 CborEncoder oicSecAclMap;
335 // ACL Map size - Number of mandatory items
336 uint8_t aclMapSize = ACL_ACES_MAP_SIZE;
339 OicSecValidity_t* validityElts = ace->validities;
342 if(validityElts->period)
346 if(validityElts->recurrences)
352 cborEncoderResult = cbor_encoder_create_map(&acesArray, &oicSecAclMap, aclMapSize);
353 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Map");
355 // Subject -- Mandatory
356 cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_SUBJECTID_NAME,
357 strlen(OIC_JSON_SUBJECTID_NAME));
358 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Name Tag.");
359 inLen = (memcmp(&(ace->subjectuuid), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
360 WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
361 if(inLen == WILDCARD_SUBJECT_ID_LEN)
363 cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, WILDCARD_RESOURCE_URI,
364 strlen(WILDCARD_RESOURCE_URI));
365 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
369 char *subject = NULL;
370 ret = ConvertUuidToStr(&ace->subjectuuid, &subject);
371 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
372 cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, subject, strlen(subject));
373 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject UUID Value.");
379 CborEncoder resources;
380 cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_RESOURCES_NAME,
381 strlen(OIC_JSON_RESOURCES_NAME));
382 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Tag.");
385 OicSecRsrc_t* rsrcElts = NULL;
386 LL_FOREACH(ace->resources, rsrcElts)
391 cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &resources, rsrcLen);
392 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Array.");
394 OicSecRsrc_t* rsrc = NULL;
395 LL_FOREACH(ace->resources, rsrc)
399 size_t rsrcMapSize = ACL_RESOURCE_MAP_SIZE;
405 cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, rsrcMapSize);
406 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
409 VERIFY_NON_NULL(TAG, rsrc->href, ERROR);
410 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
411 strlen(OIC_JSON_HREF_NAME));
412 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
413 cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->href, strlen(rsrc->href));
414 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
416 //resource type -- Mandatory
417 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
418 strlen(OIC_JSON_RT_NAME));
419 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
421 CborEncoder resourceTypes;
422 cborEncoderResult = cbor_encoder_create_array(&rMap, &resourceTypes, rsrc->typeLen);
423 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Array.");
424 for(size_t i = 0; i < rsrc->typeLen; i++)
426 cborEncoderResult = cbor_encode_text_string(&resourceTypes, rsrc->types[i], strlen(rsrc->types[i]));
427 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
429 cborEncoderResult = cbor_encoder_close_container(&rMap, &resourceTypes);
430 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing resourceTypes.");
432 //interface -- Mandatory
433 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
434 strlen(OIC_JSON_IF_NAME));
435 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
437 CborEncoder interfaces;
438 cborEncoderResult = cbor_encoder_create_array(&rMap, &interfaces, rsrc->interfaceLen);
439 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Array.");
440 for(size_t i = 0; i < rsrc->interfaceLen; i++)
442 cborEncoderResult = cbor_encode_text_string(&interfaces, rsrc->interfaces[i], strlen(rsrc->interfaces[i]));
443 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
445 cborEncoderResult = cbor_encoder_close_container(&rMap, &interfaces);
446 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing interfaces.");
451 cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
452 strlen(OIC_JSON_REL_NAME));
453 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
454 cborEncoderResult = cbor_encode_text_string(&rMap, rsrc->rel, strlen(rsrc->rel));
455 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
458 cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
459 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
461 cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &resources);
462 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Name Array.");
465 // Permissions -- Mandatory
466 cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_PERMISSION_NAME,
467 strlen(OIC_JSON_PERMISSION_NAME));
468 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Tag.");
469 cborEncoderResult = cbor_encode_int(&oicSecAclMap, ace->permission);
470 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Value.");
472 // TODO: Need to verfication for validity
473 // Validity(Time-interval) -- Not Mandatory
476 size_t validityLen = 0;
478 LL_FOREACH(ace->validities, validityElts)
483 CborEncoder validities;
484 cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_VALIDITY_NAME,
485 strlen(OIC_JSON_VALIDITY_NAME));
486 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Tag.");
487 cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &validities, validityLen);
488 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validities Array.");
490 //How to add the value w/o "title" using tinycobr...? :(
493 LL_FOREACH(ace->validities, validityElts)
495 CborEncoder validity;
496 size_t validitySize = 0;
497 if(validityElts->period)
501 if(validityElts->recurrences)
506 cborEncoderResult = cbor_encoder_create_array(&validities, &validity, validitySize);
507 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Validity Array.");
510 if (validityElts->period)
512 cborEncoderResult = cbor_encode_text_string(&validity, validityElts->period,
513 strlen(validityElts->period));
514 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Value.");
518 if (validityElts->recurrences)
520 CborEncoder recurrences;
521 cborEncoderResult = cbor_encoder_create_array(&validity, &recurrences, validityElts->recurrenceLen);
522 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array.");
524 for (size_t i = 0; i < validityElts->recurrenceLen; i++)
526 cborEncoderResult = cbor_encode_text_string(&recurrences, validityElts->recurrences[i],
527 strlen(validityElts->recurrences[i]));
528 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array Value.");
530 cborEncoderResult = cbor_encoder_close_container(&validity, &recurrences);
531 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Recurrence Array");
534 cborEncoderResult = cbor_encoder_close_container(&validities, &validity);
535 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validity Array.");
538 cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &validities);
539 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validities Array.");
542 cborEncoderResult = cbor_encoder_close_container(&acesArray, &oicSecAclMap);
543 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Map.");
547 cborEncoderResult = cbor_encoder_close_container(&aclListMap, &acesArray);
548 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Array.");
551 cborEncoderResult = cbor_encoder_close_container(&aclMap, &aclListMap);
552 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACLIST Map.");
557 cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ROWNERID_NAME,
558 strlen(OIC_JSON_ROWNERID_NAME));
559 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
560 ret = ConvertUuidToStr(&secAcl->rownerID, &rowner);
561 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
562 cborEncoderResult = cbor_encode_text_string(&aclMap, rowner, strlen(rowner));
563 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
569 cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_RT_NAME,
570 strlen(OIC_JSON_RT_NAME));
571 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
572 cborEncoderResult = cbor_encoder_create_array(&aclMap, &rtArray, 1);
573 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
574 for (size_t i = 0; i < 1; i++)
576 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_ACL,
577 strlen(OIC_RSRC_TYPE_SEC_ACL));
578 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
580 cborEncoderResult = cbor_encoder_close_container(&aclMap, &rtArray);
581 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
585 cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_IF_NAME,
586 strlen(OIC_JSON_IF_NAME));
587 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
588 cborEncoderResult = cbor_encoder_create_array(&aclMap, &ifArray, 1);
589 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
590 for (size_t i = 0; i < 1; i++)
592 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
593 strlen(OC_RSRVD_INTERFACE_DEFAULT));
594 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
596 cborEncoderResult = cbor_encoder_close_container(&aclMap, &ifArray);
597 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
600 cborEncoderResult = cbor_encoder_close_container(&encoder, &aclMap);
601 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACL Map.");
603 if (CborNoError == cborEncoderResult)
605 OIC_LOG(DEBUG, TAG, "AclToCBORPayload Successed");
606 *size = encoder.ptr - outPayload;
607 *payload = outPayload;
611 if (CborErrorOutOfMemory == cborEncoderResult)
613 OIC_LOG(DEBUG, TAG, "AclToCBORPayload:CborErrorOutOfMemory : retry with more memory");
615 // reallocate and try again!
617 // Since the allocated initial memory failed, double the memory.
618 cborLen += encoder.ptr - encoder.end;
619 cborEncoderResult = CborNoError;
620 ret = AclToCBORPayload(secAcl, payload, &cborLen);
623 else if (cborEncoderResult != CborNoError)
625 OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
630 ret = OC_STACK_ERROR;
636 // This function converts CBOR format to ACL data.
637 // Caller needs to invoke 'free' when done using
638 // note: This function is used in unit test hence not declared static,
639 OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
641 if (NULL == cborPayload || 0 == size)
645 OCStackResult ret = OC_STACK_ERROR;
646 CborValue aclCbor = { .parser = NULL };
647 CborParser parser = { .end = NULL };
648 CborError cborFindResult = CborNoError;
649 cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
651 OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
654 CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
655 cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap);
656 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
658 while (cbor_value_is_valid(&aclMap))
660 char* tagName = NULL;
662 CborType type = cbor_value_get_type(&aclMap);
663 if (type == CborTextStringType)
665 cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL);
666 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
667 cborFindResult = cbor_value_advance(&aclMap);
668 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
672 if (strcmp(tagName, OIC_JSON_ACLIST_NAME) == 0)
675 CborValue aclistMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
676 cborFindResult = cbor_value_enter_container(&aclMap, &aclistMap);
677 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACLIST Map.");
680 while (cbor_value_is_valid(&aclistMap))
684 CborType acType = cbor_value_get_type(&aclistMap);
685 if (acType == CborTextStringType)
687 cborFindResult = cbor_value_dup_text_string(&aclistMap, &acName, &readLen, NULL);
688 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACLIST Map.");
689 cborFindResult = cbor_value_advance(&aclistMap);
690 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACLIST Map.");
695 if (strcmp(acName, OIC_JSON_ACES_NAME) == 0)
698 CborValue acesArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
699 cborFindResult = cbor_value_enter_container(&aclistMap, &acesArray);
700 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACES Array.");
703 while (cbor_value_is_valid(&acesArray))
706 CborValue aceMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
707 cborFindResult = cbor_value_enter_container(&acesArray, &aceMap);
708 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACE Map.");
710 OicSecAce_t *ace = NULL;
711 ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
712 VERIFY_NON_NULL(TAG, ace, ERROR);
713 LL_APPEND(acl->aces, ace);
715 VERIFY_NON_NULL(TAG, acl, ERROR);
717 while (cbor_value_is_valid(&aceMap))
721 CborType type = cbor_value_get_type(&aceMap);
722 if (type == CborTextStringType)
724 cborFindResult = cbor_value_dup_text_string(&aceMap, &name, &len, NULL);
725 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACE Map.");
726 cborFindResult = cbor_value_advance(&aceMap);
727 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACE Map.");
731 // Subject -- Mandatory
732 if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
734 char *subject = NULL;
735 cborFindResult = cbor_value_dup_text_string(&aceMap, &subject, &len, NULL);
736 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value.");
737 if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0)
739 ace->subjectuuid.id[0] = '*';
743 ret = ConvertStrToUuid(subject, &ace->subjectuuid);
744 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
749 // Resources -- Mandatory
750 if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
752 CborValue resources = { .parser = NULL };
753 cborFindResult = cbor_value_enter_container(&aceMap, &resources);
754 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array.");
756 while (cbor_value_is_valid(&resources))
759 CborValue rMap = { .parser = NULL };
760 cborFindResult = cbor_value_enter_container(&resources, &rMap);
761 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
763 OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
764 VERIFY_NON_NULL(TAG, rsrc, ERROR);
765 LL_APPEND(ace->resources, rsrc);
767 while(cbor_value_is_valid(&rMap))
769 char *rMapName = NULL;
770 size_t rMapNameLen = 0;
771 cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
772 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
773 cborFindResult = cbor_value_advance(&rMap);
774 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
777 if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
779 cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->href, &len, NULL);
780 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
784 if (0 == strcmp(OIC_JSON_RT_NAME, rMapName) && cbor_value_is_array(&rMap))
786 cbor_value_get_array_length(&rMap, &rsrc->typeLen);
787 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT array length.");
788 VERIFY_SUCCESS(TAG, (0 != rsrc->typeLen), ERROR);
790 rsrc->types = (char**)OICCalloc(rsrc->typeLen, sizeof(char*));
791 VERIFY_NON_NULL(TAG, rsrc->types, ERROR);
793 CborValue resourceTypes;
794 cborFindResult = cbor_value_enter_container(&rMap, &resourceTypes);
795 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering RT Array.");
797 for(size_t i = 0; cbor_value_is_valid(&resourceTypes) && cbor_value_is_text_string(&resourceTypes); i++)
799 cborFindResult = cbor_value_dup_text_string(&resourceTypes, &(rsrc->types[i]), &readLen, NULL);
800 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding resource type.");
801 cborFindResult = cbor_value_advance(&resourceTypes);
802 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing resource type.");
807 if (0 == strcmp(OIC_JSON_IF_NAME, rMapName) && cbor_value_is_array(&rMap))
809 cbor_value_get_array_length(&rMap, &rsrc->interfaceLen);
810 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF array length.");
811 VERIFY_SUCCESS(TAG, (0 != rsrc->interfaceLen), ERROR);
813 rsrc->interfaces = (char**)OICCalloc(rsrc->interfaceLen, sizeof(char*));
814 VERIFY_NON_NULL(TAG, rsrc->interfaces, ERROR);
816 CborValue interfaces;
817 cborFindResult = cbor_value_enter_container(&rMap, &interfaces);
818 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering IF Array.");
820 for(size_t i = 0; cbor_value_is_valid(&interfaces) && cbor_value_is_text_string(&interfaces); i++)
822 cborFindResult = cbor_value_dup_text_string(&interfaces, &(rsrc->interfaces[i]), &readLen, NULL);
823 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF type.");
824 cborFindResult = cbor_value_advance(&interfaces);
825 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing IF type.");
830 if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
832 cborFindResult = cbor_value_dup_text_string(&rMap, &rsrc->rel, &len, NULL);
833 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
836 if (cbor_value_is_valid(&rMap))
838 cborFindResult = cbor_value_advance(&rMap);
839 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
844 if (cbor_value_is_valid(&resources))
846 cborFindResult = cbor_value_advance(&resources);
847 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
852 // Permissions -- Mandatory
853 if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
856 cborFindResult = cbor_value_get_uint64(&aceMap, &tmp64);
857 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value.");
858 ace->permission = (uint16_t)tmp64;
861 // TODO: Need to verfication for validity
862 // Validity -- Not mandatory
863 if(strcmp(name, OIC_JSON_VALIDITY_NAME) == 0)
865 CborValue validitiesMap = {.parser = NULL};
866 size_t validitySize = 0;
868 cborFindResult = cbor_value_get_array_length(&aceMap, &validitySize);
869 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Validity Array Length.");
871 cborFindResult = cbor_value_enter_container(&aceMap, &validitiesMap);
872 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Array Map.");
874 while(cbor_value_is_valid(&validitiesMap))
876 OicSecValidity_t* validity = (OicSecValidity_t*)OICCalloc(1, sizeof(OicSecValidity_t));
877 VERIFY_NON_NULL(TAG, validity, ERROR);
878 LL_APPEND(ace->validities, validity);
880 CborValue validityMap = {.parser = NULL};
882 cborFindResult = cbor_value_enter_container(&validitiesMap, &validityMap);
883 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a validity Map.");
886 cborFindResult =cbor_value_dup_text_string(&validityMap, &validity->period, &len, NULL);
887 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period value.");
889 //recurrence (string array)
890 CborValue recurrenceMap = {.parser = NULL};
891 cborFindResult = cbor_value_enter_container(&validityMap, &recurrenceMap);
892 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence array.");
894 cborFindResult = cbor_value_get_array_length(&recurrenceMap, &validity->recurrenceLen);
895 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array.");
897 validity->recurrences = (char**)OICCalloc(validity->recurrenceLen, sizeof(char*));
898 VERIFY_NON_NULL(TAG, validity->recurrences, ERROR);
900 for(size_t i = 0; cbor_value_is_text_string(&recurrenceMap) && i < validity->recurrenceLen; i++)
902 cborFindResult = cbor_value_dup_text_string(&recurrenceMap, &validity->recurrences[i], &len, NULL);
903 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a recurrence Value.");
905 cborFindResult = cbor_value_advance(&recurrenceMap);
906 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a recurrences Array.");
909 cborFindResult = cbor_value_advance(&validitiesMap);
910 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a validities Array.");
916 if (type != CborMapType && cbor_value_is_valid(&aceMap))
918 cborFindResult = cbor_value_advance(&aceMap);
919 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array.");
923 if (cbor_value_is_valid(&acesArray))
925 cborFindResult = cbor_value_advance(&acesArray);
926 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array.");
933 if (cbor_value_is_valid(&aclistMap))
935 cborFindResult = cbor_value_advance(&aclistMap);
936 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACLIST Map.");
941 //rownerID -- Mandatory
942 if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0)
944 char *stRowner = NULL;
945 cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
946 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
947 ret = ConvertStrToUuid(stRowner, &acl->rownerID);
948 VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
953 if (cbor_value_is_valid(&aclMap))
955 cborFindResult = cbor_value_advance(&aclMap);
956 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map.");
961 if (cborFindResult != CborNoError)
963 OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl");
972 * This method removes ACE for the subject and resource from the ACL
974 * @param subject of the ACE
975 * @param resource of the ACE
978 * ::OC_STACK_RESOURCE_DELETED on success
979 * ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
980 * ::OC_STACK_INVALID_PARAM on invalid parameter
982 OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
984 OIC_LOG(DEBUG, TAG, "IN RemoveACE");
986 OicSecAce_t *ace = NULL;
987 OicSecAce_t *tempAce = NULL;
988 bool deleteFlag = false;
989 OCStackResult ret = OC_STACK_NO_RESOURCE;
991 if (memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
993 OIC_LOG_V(ERROR, TAG, "%s received invalid parameter", __func__ );
994 return OC_STACK_INVALID_PARAM;
997 //If resource is NULL then delete all the ACE for the subject.
998 if (NULL == resource || resource[0] == '\0')
1000 LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1002 if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
1004 LL_DELETE(gAcl->aces, ace);
1012 //Looping through ACL to find the right ACE to delete. If the required resource is the only
1013 //resource in the ACE for the subject then delete the whole ACE. If there are more resources
1014 //than the required resource in the ACE, for the subject then just delete the resource from
1015 //the resource array
1016 LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
1018 if (memcmp(ace->subjectuuid.id, subject->id, sizeof(subject->id)) == 0)
1020 OicSecRsrc_t* rsrc = NULL;
1021 OicSecRsrc_t* tempRsrc = NULL;
1022 LL_FOREACH_SAFE(ace->resources, rsrc, tempRsrc)
1024 if(strcmp(rsrc->href, resource) == 0)
1026 LL_DELETE(ace->resources, rsrc);
1032 //If resource list is empty
1033 if(NULL == ace->resources && true == deleteFlag)
1035 //Remove the ACE from ACL
1036 LL_DELETE(gAcl->aces, ace);
1045 // In case of unit test do not update persistant storage.
1046 if (memcmp(subject->id, &WILDCARD_SUBJECT_B64_ID, sizeof(subject->id)) == 0)
1048 ret = OC_STACK_RESOURCE_DELETED;
1052 uint8_t *payload = NULL;
1054 if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1056 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size))
1058 ret = OC_STACK_RESOURCE_DELETED;
1068 * This method parses the query string received for REST requests and
1069 * retrieves the 'subject' field.
1071 * @param query querystring passed in REST request
1072 * @param subject subject UUID parsed from query string
1074 * @return true if query parsed successfully and found 'subject', else false.
1076 static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
1078 OicParseQueryIter_t parseIter = { .attrPos = NULL };
1080 ParseQueryIterInit((unsigned char *) query, &parseIter);
1082 while (GetNextQuery (&parseIter))
1084 if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, parseIter.attrLen) == 0)
1086 char strUuid[STRING_UUID_SIZE] = {0};
1087 VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1088 memcpy(strUuid, parseIter.valPos, parseIter.valLen);
1089 OCStackResult res = ConvertStrToUuid(strUuid, subject);
1090 VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
1100 * This method parses the query string received for REST requests and
1101 * retrieves the 'resource' field.
1103 * @param query querystring passed in REST request
1104 * @param resource resource parsed from query string
1105 * @param resourceSize size of the memory pointed to resource
1107 * @return true if query parsed successfully and found 'resource', else false.
1109 static bool GetResourceFromQueryString(const char *query, char *resource, size_t resourceSize)
1111 OicParseQueryIter_t parseIter = { .attrPos = NULL };
1113 ParseQueryIterInit((unsigned char *) query, &parseIter);
1115 while (GetNextQuery (&parseIter))
1117 if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen)
1120 VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
1121 OICStrcpy(resource, resourceSize, (char *) parseIter.valPos);
1131 static size_t GetNumberOfResource(OicSecRsrc_t* resources)
1136 OicSecRsrc_t* rsrc = NULL;
1137 LL_FOREACH(resources, rsrc)
1145 static size_t GetNumberOfValidity(OicSecValidity_t* val)
1151 OicSecValidity_t* temp = NULL;
1152 LL_FOREACH(val, temp)
1161 static bool IsSameStringArray(char** strArr1, size_t strArr1Len,
1162 char** strArr2, size_t strArr2Len)
1165 if(NULL == strArr1 && NULL == strArr2)
1170 if(strArr1 && strArr2 && NULL == *strArr1 && NULL == *strArr2)
1175 if(strArr1 && strArr2)
1177 if(*strArr1 && *strArr2 && strArr1Len == strArr2Len)
1179 size_t matchedStr = 0;
1180 for(size_t i = 0; i < strArr1Len; i++)
1182 for(size_t j = 0; j < strArr2Len; j++)
1184 if(strcmp(strArr1[i], strArr2[j]) == 0)
1190 if(matchedStr == strArr1Len)
1200 static bool IsSameResources(OicSecRsrc_t* resources1, OicSecRsrc_t* resources2)
1202 size_t numOfRsrc1 = 0;
1203 size_t numOfRsrc2 = 0;
1204 size_t numOfMatchedRsrc = 0;
1205 OicSecRsrc_t* rsrc1 = NULL;
1206 OicSecRsrc_t* rsrc2 = NULL;
1208 if(NULL == resources1 && NULL == resources2)
1213 if(resources1 && resources2)
1215 numOfRsrc1 = GetNumberOfResource(resources1);
1216 numOfRsrc2 = GetNumberOfResource(resources2);
1218 if(0 == numOfRsrc1 && 0 == numOfRsrc2)
1223 LL_FOREACH(resources1, rsrc1)
1226 LL_FOREACH(resources2, rsrc2)
1230 if(strcmp(rsrc1->href, rsrc2->href) == 0 &&
1231 IsSameStringArray(rsrc1->interfaces, rsrc1->interfaceLen,
1232 rsrc2->interfaces, rsrc2->interfaceLen) &&
1233 IsSameStringArray(rsrc1->types, rsrc1->typeLen,
1234 rsrc2->types, rsrc2->typeLen))
1236 // TODO: Update codes to compare 'rel' property
1243 if(numOfMatchedRsrc == numOfRsrc1)
1252 static bool IsSameValidities(OicSecValidity_t* validities1, OicSecValidity_t* validities2)
1254 size_t numOfVal1 = 0;
1255 size_t numOfVal2 = 0;
1256 size_t numOfMatchedVal = 0;
1257 OicSecValidity_t* val1 = NULL;
1258 OicSecValidity_t* val2 = NULL;
1260 if(NULL == validities1 && NULL == validities2)
1265 if(validities1 && validities2)
1267 numOfVal1 = GetNumberOfValidity(validities1);
1268 numOfVal2 = GetNumberOfValidity(validities2);
1269 if(0 == numOfVal1 && 0 == numOfVal2)
1274 if(numOfVal1 == numOfVal2)
1276 LL_FOREACH(validities1, val1)
1278 LL_FOREACH(validities2, val2)
1280 if(strcmp(val1->period, val2->period) == 0 &&
1281 IsSameStringArray(val1->recurrences, val1->recurrenceLen,
1282 val2->recurrences, val2->recurrenceLen))
1288 if(numOfVal1 == numOfMatchedVal)
1298 static bool IsSameACE(OicSecAce_t* ace1, OicSecAce_t* ace2)
1302 if(memcmp(ace1->subjectuuid.id, ace2->subjectuuid.id, sizeof(ace1->subjectuuid.id)) != 0)
1307 if(false == IsSameResources(ace1->resources, ace2->resources))
1312 if(ace1->permission != ace2->permission)
1317 if(false == IsSameValidities(ace1->validities, ace2->validities))
1328 static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
1330 OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
1331 uint8_t* payload = NULL;
1333 OCEntityHandlerResult ehRet;
1335 OicUuid_t subject = {.id= { 0 } };
1337 // In case, 'subject' field is included in REST request.
1338 if (ehRequest->query && GetSubjectFromQueryString(ehRequest->query, &subject))
1340 OIC_LOG(DEBUG,TAG,"'subject' field is inculded in REST request.");
1341 OIC_LOG(DEBUG, TAG, "HandleACLGetRequest processing query");
1343 char resource[MAX_URI_LENGTH] = { 0 };
1345 OicSecAce_t *savePtr = NULL;
1346 const OicSecAce_t *currentAce = NULL;
1347 OicSecAcl_t targetAcl;
1349 memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t));
1350 targetAcl.aces = NULL;
1352 // 'Subject' field is MUST for processing a querystring in REST request.
1353 GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1356 * TODO : Currently, this code only provides one ACE for a Subject.
1357 * Below code needs to be updated for scenarios when Subject have
1358 * multiple ACE's in ACL resource.
1360 while ((currentAce = GetACLResourceData(&subject, &savePtr)))
1362 targetAcl.aces = (OicSecAce_t*)currentAce;
1365 * If REST querystring contains a specific resource, we need
1366 * to search for that resource in ACE.
1368 if (resource[0] != '\0')
1370 OicSecRsrc_t *rsrc = NULL;
1371 LL_FOREACH(currentAce->resources, rsrc)
1373 if(0 == strcmp(rsrc->href, resource) ||
1374 0 == strcmp(WILDCARD_RESOURCE_URI, rsrc->href))
1376 // Convert ACL data into CBOR format for transmission
1377 if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1379 ehRet = OC_EH_ERROR;
1387 // Convert ACL data into CBOR format for transmission
1388 if (OC_STACK_OK != AclToCBORPayload(&targetAcl, &payload, &size))
1390 ehRet = OC_EH_ERROR;
1396 // In case, 'subject' field is not included in REST request.
1399 OIC_LOG(DEBUG,TAG,"'subject' field is not inculded in REST request.");
1400 // Convert ACL data into CBOR format for transmission.
1401 if (OC_STACK_OK != AclToCBORPayload(gAcl, &payload, &size))
1403 ehRet = OC_EH_ERROR;
1407 // A device should always have a default acl. Therefore, payload should never be NULL.
1408 ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
1409 OIC_LOG(DEBUG, TAG, "ACL payload with GET response");
1410 OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
1412 //Send payload to request originator
1413 ehRet = ((SendSRMResponse(ehRequest, ehRet, payload, size)) == OC_STACK_OK) ?
1414 OC_EH_OK : OC_EH_ERROR;
1418 OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1422 static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *ehRequest)
1424 OIC_LOG(INFO, TAG, "HandleACLPostRequest processing the request");
1425 OCEntityHandlerResult ehRet = OC_EH_OK;
1427 // Convert CBOR into ACL data and update to SVR buffers. This will also validate the ACL data received.
1428 uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
1429 size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
1432 OicSecAcl_t *newAcl = NULL;
1433 OicSecAcl_t newAceList;
1434 OIC_LOG(DEBUG, TAG, "ACL payload from POST request << ");
1435 OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
1437 newAcl = CBORPayloadToAcl(payload, size);
1440 bool isNewAce = true;
1441 OicSecAce_t* existAce = NULL;
1442 OicSecAce_t* newAce = NULL;
1443 OicSecAce_t* tempAce1 = NULL;
1444 OicSecAce_t* tempAce2 = NULL;
1445 newAceList.aces = NULL;
1447 LL_FOREACH_SAFE(newAcl->aces, newAce, tempAce1)
1450 LL_FOREACH_SAFE(gAcl->aces, existAce, tempAce2)
1452 if(IsSameACE(newAce, existAce))
1459 OIC_LOG(DEBUG, TAG, "NEW ACE dectected.");
1461 OicSecAce_t* insertAce = DuplicateACE(newAce);
1464 OIC_LOG(DEBUG, TAG, "Appending new ACE..");
1465 LL_PREPEND(gAcl->aces, insertAce);
1469 OIC_LOG(ERROR, TAG, "Failed to duplicate ACE.");
1470 ehRet = OC_EH_ERROR;
1475 DeleteACLList(newAcl);
1477 if(OC_EH_OK == ehRet)
1480 uint8_t *cborPayload = NULL;
1481 if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size))
1483 if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK)
1485 ehRet = OC_EH_CHANGED;
1487 OICFree(cborPayload);
1490 if(OC_EH_CHANGED != ehRet)
1492 ehRet = OC_EH_ERROR;
1498 //Send response to request originator
1499 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1500 OC_EH_OK : OC_EH_ERROR;
1502 OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
1506 static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest *ehRequest)
1508 OIC_LOG(DEBUG, TAG, "Processing ACLDeleteRequest");
1509 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1510 OicUuid_t subject = { .id= { 0 } };
1511 char resource[MAX_URI_LENGTH] = { 0 };
1513 VERIFY_NON_NULL(TAG, ehRequest->query, ERROR);
1515 // 'Subject' field is MUST for processing a querystring in REST request.
1516 VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR);
1518 GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
1520 if (OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
1522 ehRet = OC_EH_RESOURCE_DELETED;
1526 //Send response to request originator
1527 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1528 OC_EH_OK : OC_EH_ERROR;
1533 OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest,
1534 void* callbackParameter)
1536 OIC_LOG(DEBUG, TAG, "Received request ACLEntityHandler");
1537 (void)callbackParameter;
1538 OCEntityHandlerResult ehRet = OC_EH_ERROR;
1545 if (flag & OC_REQUEST_FLAG)
1547 // TODO : Handle PUT method
1548 OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
1549 switch (ehRequest->method)
1552 ehRet = HandleACLGetRequest(ehRequest);
1556 ehRet = HandleACLPostRequest(ehRequest);
1559 case OC_REST_DELETE:
1560 ehRet = HandleACLDeleteRequest(ehRequest);
1564 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
1565 OC_EH_OK : OC_EH_ERROR;
1573 * This internal method is used to create '/oic/sec/acl' resource.
1575 static OCStackResult CreateACLResource()
1579 ret = OCCreateResource(&gAclHandle,
1580 OIC_RSRC_TYPE_SEC_ACL,
1581 OC_RSRVD_INTERFACE_DEFAULT,
1585 OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
1587 if (OC_STACK_OK != ret)
1589 OIC_LOG(FATAL, TAG, "Unable to instantiate ACL resource");
1590 DeInitACLResource();
1595 // This function sets the default ACL and is defined for the unit test only.
1596 OCStackResult SetDefaultACL(OicSecAcl_t *acl)
1602 OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
1604 OCStackResult ret = OC_STACK_ERROR;
1605 OicUuid_t ownerId = { .id = { 0 } };
1606 OicSecAcl_t *acl = NULL;
1607 OicSecAce_t *ace = NULL;
1608 OicSecRsrc_t* resRsrc = NULL;
1609 OicSecRsrc_t* deviceRsrc = NULL;
1610 OicSecRsrc_t* platformRsrc = NULL;
1611 OicSecRsrc_t* aclRsrc = NULL;
1612 OicSecRsrc_t* doxmRsrc = NULL;
1613 OicSecRsrc_t* pstatRsrc = NULL;
1616 * TODO In future, when new virtual resources will be added in OIC
1617 * specification, Iotivity stack should be able to add them in
1618 * existing SVR database. To support this, we need to add 'versioning'
1619 * mechanism in SVR database.
1624 return OC_STACK_INVALID_PARAM;
1627 acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
1628 VERIFY_NON_NULL(TAG, acl, ERROR);
1630 ace = (OicSecAce_t *) OICCalloc(1, sizeof(OicSecAce_t));
1631 VERIFY_NON_NULL(TAG, ace, ERROR);
1633 LL_APPEND(acl->aces, ace);
1635 // Subject -- Mandatory
1636 memcpy(ace->subjectuuid.id, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t));
1638 // Resources -- Mandatory
1640 resRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1641 VERIFY_NON_NULL(TAG, resRsrc, ERROR);
1642 LL_APPEND(ace->resources, resRsrc);
1643 resRsrc->href = OICStrdup(OC_RSRVD_WELL_KNOWN_URI);
1644 VERIFY_NON_NULL(TAG, (resRsrc->href), ERROR);
1645 resRsrc->typeLen = 1;
1646 resRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1647 VERIFY_NON_NULL(TAG, resRsrc->types, ERROR);
1648 resRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_RES);
1649 VERIFY_NON_NULL(TAG, resRsrc->types[0], ERROR);
1650 resRsrc->interfaceLen = 2;
1651 resRsrc->interfaces = (char**)OICCalloc(resRsrc->interfaceLen, sizeof(char*));
1652 VERIFY_NON_NULL(TAG, resRsrc->interfaces, ERROR);
1653 resRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1654 VERIFY_NON_NULL(TAG, resRsrc->interfaces[0], ERROR);
1655 resRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1656 VERIFY_NON_NULL(TAG, resRsrc->interfaces[1], ERROR);
1659 deviceRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1660 VERIFY_NON_NULL(TAG, deviceRsrc, ERROR);
1661 LL_APPEND(ace->resources, deviceRsrc);
1662 deviceRsrc->href = OICStrdup(OC_RSRVD_DEVICE_URI);
1663 VERIFY_NON_NULL(TAG, (deviceRsrc->href), ERROR);
1664 deviceRsrc->typeLen = 1;
1665 deviceRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1666 VERIFY_NON_NULL(TAG, deviceRsrc->types, ERROR);
1667 deviceRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_DEVICE);
1668 VERIFY_NON_NULL(TAG, deviceRsrc->types[0], ERROR);
1669 deviceRsrc->interfaceLen = 2;
1670 deviceRsrc->interfaces = (char**)OICCalloc(deviceRsrc->interfaceLen, sizeof(char*));
1671 VERIFY_NON_NULL(TAG, deviceRsrc->interfaces, ERROR);
1672 deviceRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1673 VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[0], ERROR);
1674 deviceRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1675 VERIFY_NON_NULL(TAG, deviceRsrc->interfaces[1], ERROR);
1678 platformRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1679 VERIFY_NON_NULL(TAG, platformRsrc, ERROR);
1680 LL_APPEND(ace->resources, platformRsrc);
1681 platformRsrc->href = OICStrdup(OC_RSRVD_PLATFORM_URI);
1682 VERIFY_NON_NULL(TAG, (platformRsrc->href), ERROR);
1683 platformRsrc->typeLen = 1;
1684 platformRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1685 VERIFY_NON_NULL(TAG, platformRsrc->types, ERROR);
1686 platformRsrc->types[0] = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM);
1687 VERIFY_NON_NULL(TAG, platformRsrc->types[0], ERROR);
1688 platformRsrc->interfaceLen = 2;
1689 platformRsrc->interfaces = (char**)OICCalloc(platformRsrc->interfaceLen, sizeof(char*));
1690 VERIFY_NON_NULL(TAG, platformRsrc->interfaces, ERROR);
1691 platformRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1692 VERIFY_NON_NULL(TAG, platformRsrc->interfaces[0], ERROR);
1693 platformRsrc->interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_READ);
1694 VERIFY_NON_NULL(TAG, platformRsrc->interfaces[1], ERROR);
1697 aclRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1698 VERIFY_NON_NULL(TAG, aclRsrc, ERROR);
1699 LL_APPEND(ace->resources, aclRsrc);
1700 aclRsrc->href = OICStrdup(OIC_RSRC_ACL_URI);
1701 VERIFY_NON_NULL(TAG, (aclRsrc->href), ERROR);
1702 aclRsrc->typeLen = 1;
1703 aclRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1704 VERIFY_NON_NULL(TAG, aclRsrc->types, ERROR);
1705 aclRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_ACL);
1706 VERIFY_NON_NULL(TAG, aclRsrc->types[0], ERROR);
1707 aclRsrc->interfaceLen = 1;
1708 aclRsrc->interfaces = (char**)OICCalloc(aclRsrc->interfaceLen, sizeof(char*));
1709 VERIFY_NON_NULL(TAG, aclRsrc->interfaces, ERROR);
1710 aclRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1711 VERIFY_NON_NULL(TAG, aclRsrc->interfaces[0], ERROR);
1714 doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1715 VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
1716 LL_APPEND(ace->resources, doxmRsrc);
1717 doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
1718 VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
1719 doxmRsrc->typeLen = 1;
1720 doxmRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1721 VERIFY_NON_NULL(TAG, doxmRsrc->types, ERROR);
1722 doxmRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_DOXM);
1723 VERIFY_NON_NULL(TAG, doxmRsrc->types[0], ERROR);
1724 doxmRsrc->interfaceLen = 1;
1725 doxmRsrc->interfaces = (char**)OICCalloc(doxmRsrc->interfaceLen, sizeof(char*));
1726 VERIFY_NON_NULL(TAG, doxmRsrc->interfaces, ERROR);
1727 doxmRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1728 VERIFY_NON_NULL(TAG, doxmRsrc->interfaces[0], ERROR);
1731 pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1732 VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
1733 LL_APPEND(ace->resources, pstatRsrc);
1734 pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
1735 VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
1736 pstatRsrc->typeLen = 1;
1737 pstatRsrc->types = (char**)OICCalloc(1, sizeof(char*));
1738 VERIFY_NON_NULL(TAG, pstatRsrc->types, ERROR);
1739 pstatRsrc->types[0] = OICStrdup(OIC_RSRC_TYPE_SEC_PSTAT);
1740 VERIFY_NON_NULL(TAG, pstatRsrc->types[0], ERROR);
1741 pstatRsrc->interfaceLen = 1;
1742 pstatRsrc->interfaces = (char**)OICCalloc(pstatRsrc->interfaceLen, sizeof(char*));
1743 VERIFY_NON_NULL(TAG, pstatRsrc->interfaces, ERROR);
1744 pstatRsrc->interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
1745 VERIFY_NON_NULL(TAG, pstatRsrc->interfaces[0], ERROR);
1747 ace->permission = PERMISSION_READ;
1748 ace->validities = NULL;
1750 // Device ID is the owner of this default ACL
1751 if (GetDoxmResourceData() != NULL)
1753 ret = GetDoxmDeviceID(&ownerId);
1754 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
1758 OCRandomUuidResult rdm = OCGenerateUuid(ownerId.id);
1759 VERIFY_SUCCESS(TAG, RAND_UUID_OK == rdm, FATAL);
1762 memcpy(&acl->rownerID, &ownerId, sizeof(OicUuid_t));
1769 if (ret != OC_STACK_OK)
1778 OCStackResult InitACLResource()
1780 OCStackResult ret = OC_STACK_ERROR;
1782 uint8_t *data = NULL;
1784 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &data, &size);
1785 // If database read failed
1786 if (OC_STACK_OK != ret)
1788 OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
1792 // Read ACL resource from PS
1793 gAcl = CBORPayloadToAcl(data, size);
1796 * If SVR database in persistent storage got corrupted or
1797 * is not available for some reason, a default ACL is created
1798 * which allows user to initiate ACL provisioning again.
1802 ret = GetDefaultACL(&gAcl);
1803 if (OC_STACK_OK != ret)
1805 OIC_LOG(ERROR, TAG, "Failed to create default ACL");
1807 // TODO Needs to update persistent storage
1809 VERIFY_NON_NULL(TAG, gAcl, FATAL);
1811 // Instantiate 'oic.sec.acl'
1812 ret = CreateACLResource();
1815 if (OC_STACK_OK != ret)
1817 DeInitACLResource();
1822 OCStackResult DeInitACLResource()
1824 OCStackResult ret = OCDeleteResource(gAclHandle);
1829 DeleteACLList(gAcl);
1835 const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t **savePtr)
1837 OicSecAce_t *ace = NULL;
1838 OicSecAce_t *begin = NULL;
1840 if (NULL == subjectId)
1846 * savePtr MUST point to NULL if this is the 'first' call to retrieve ACL for
1849 if (NULL == *savePtr)
1856 * If this is a 'successive' call, search for location pointed by
1857 * savePtr and assign 'begin' to the next ACL after it in the linked
1858 * list and start searching from there.
1860 LL_FOREACH(gAcl->aces, ace)
1862 if (ace == *savePtr)
1869 // Find the next ACL corresponding to the 'subjectID' and return it.
1870 LL_FOREACH(begin, ace)
1872 if (memcmp(&(ace->subjectuuid), subjectId, sizeof(OicUuid_t)) == 0)
1879 // Cleanup in case no ACL is found
1884 OCStackResult InstallNewACL(const uint8_t *cborPayload, const size_t size)
1886 OCStackResult ret = OC_STACK_ERROR;
1888 // Convert CBOR format to ACL data. This will also validate the ACL data received.
1889 OicSecAcl_t* newAcl = CBORPayloadToAcl(cborPayload, size);
1893 // Append the new ACL to existing ACL
1894 OicSecAce_t* newAce = NULL;
1895 LL_FOREACH(newAcl->aces, newAce)
1897 LL_APPEND(gAcl->aces, newAce);
1901 uint8_t *payload = NULL;
1902 if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
1904 if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
1916 * This function generates default ACE for security resource in case of owned status.
1918 * @return Default ACE for security resource.
1920 static OicSecAce_t* GetSecDefaultACE()
1922 const int NUM_OF_DOXM_RT = 1;
1923 const int NUM_OF_DOXM_IF = 1;
1924 const int NUM_OF_PSTAT_RT = 1;
1925 const int NUM_OF_PSTAT_IF = 1;
1926 const char *doxmRt[] = { OIC_RSRC_TYPE_SEC_DOXM };
1927 const char *pstatRt[] = { OIC_RSRC_TYPE_SEC_PSTAT };
1928 const char *doxmIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
1929 const char *pstatIf[] = { OC_RSRVD_INTERFACE_DEFAULT };
1930 OicSecRsrc_t* doxmRsrc = NULL;
1931 OicSecRsrc_t* pstatRsrc = NULL;
1933 //Generate default ACE
1934 OicSecAce_t* newAce = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
1935 VERIFY_NON_NULL(TAG, newAce, ERROR);
1937 // Subject -- Mandatory
1938 memcpy(newAce->subjectuuid.id, &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN);
1940 //Resources -- Mandatory
1942 doxmRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1943 VERIFY_NON_NULL(TAG, doxmRsrc, ERROR);
1944 LL_APPEND(newAce->resources, doxmRsrc);
1946 doxmRsrc->href = OICStrdup(OIC_RSRC_DOXM_URI);
1947 VERIFY_NON_NULL(TAG, (doxmRsrc->href), ERROR);
1949 doxmRsrc->typeLen = NUM_OF_DOXM_RT;
1950 doxmRsrc->types = (char**)OICCalloc(NUM_OF_DOXM_RT, sizeof(char*));
1951 VERIFY_NON_NULL(TAG, (doxmRsrc->types), ERROR);
1952 for(int i = 0; i < NUM_OF_DOXM_RT; i++)
1954 doxmRsrc->types[i] = OICStrdup(doxmRt[i]);
1955 VERIFY_NON_NULL(TAG, (doxmRsrc->types[i]), ERROR);
1958 doxmRsrc->interfaceLen = NUM_OF_DOXM_IF;
1959 doxmRsrc->interfaces = (char**)OICCalloc(NUM_OF_DOXM_IF, sizeof(char*));
1960 VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces), ERROR);
1961 for(int i = 0; i < NUM_OF_DOXM_IF; i++)
1963 doxmRsrc->interfaces[i] = OICStrdup(doxmIf[i]);
1964 VERIFY_NON_NULL(TAG, (doxmRsrc->interfaces[i]), ERROR);
1968 pstatRsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
1969 VERIFY_NON_NULL(TAG, pstatRsrc, ERROR);
1970 LL_APPEND(newAce->resources, pstatRsrc);
1972 pstatRsrc->href = OICStrdup(OIC_RSRC_PSTAT_URI);
1973 VERIFY_NON_NULL(TAG, (pstatRsrc->href), ERROR);
1975 pstatRsrc->typeLen = NUM_OF_PSTAT_RT;
1976 pstatRsrc->types = (char**)OICCalloc(NUM_OF_PSTAT_RT, sizeof(char*));
1977 VERIFY_NON_NULL(TAG, (pstatRsrc->types), ERROR);
1978 for(int i = 0; i < NUM_OF_PSTAT_RT; i++)
1980 pstatRsrc->types[i] = OICStrdup(pstatRt[i]);
1981 VERIFY_NON_NULL(TAG, (pstatRsrc->types[i]), ERROR);
1984 pstatRsrc->interfaceLen = NUM_OF_PSTAT_IF;
1985 pstatRsrc->interfaces = (char**)OICCalloc(NUM_OF_PSTAT_IF, sizeof(char*));
1986 VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces), ERROR);
1987 for(int i = 0; i < NUM_OF_PSTAT_IF; i++)
1989 pstatRsrc->interfaces[i] = OICStrdup(pstatIf[i]);
1990 VERIFY_NON_NULL(TAG, (pstatRsrc->interfaces[i]), ERROR);
1993 // Permissions -- Mandatory
1994 newAce->permission = PERMISSION_READ;
1996 //Period -- Not Mandatory
1997 newAce->validities = NULL;
2006 OCStackResult UpdateDefaultSecProvACE()
2008 OCStackResult ret = OC_STACK_OK;
2009 OicSecAce_t *ace = NULL;
2010 OicSecAce_t *tempAce = NULL;
2014 int matchedRsrc = 0;
2015 bool isRemoved = false;
2017 LL_FOREACH_SAFE(gAcl->aces, ace, tempAce)
2019 //Find default security resource ACL
2020 if(memcmp(&ace->subjectuuid, &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0 &&
2021 ((PERMISSION_READ | PERMISSION_WRITE) == ace->permission))
2025 OicSecRsrc_t* rsrc = NULL;
2026 LL_FOREACH(ace->resources, rsrc)
2028 if(strncmp(rsrc->href, OIC_RSRC_DOXM_URI,
2029 strlen(OIC_RSRC_DOXM_URI) + 1) == 0 ||
2030 strncmp(rsrc->href, OIC_RSRC_CRED_URI,
2031 strlen(OIC_RSRC_CRED_URI) + 1) == 0 ||
2032 strncmp(rsrc->href, OIC_RSRC_ACL_URI,
2033 strlen(OIC_RSRC_ACL_URI) + 1) == 0 ||
2034 strncmp(rsrc->href, OIC_RSRC_PSTAT_URI,
2035 strlen(OIC_RSRC_PSTAT_URI) + 1) == 0)
2041 //If default security resource ACL is detected, delete it.
2042 if(NUMBER_OF_SEC_PROV_RSCS == matchedRsrc)
2044 LL_DELETE(gAcl->aces, ace);
2054 * Generate new security resource ACE as follows :
2056 * resources : '/oic/sec/doxm', '/oic/sec/pstat'
2059 OicSecAce_t *secDefaultAce = GetSecDefaultACE();
2062 LL_APPEND(gAcl->aces, secDefaultAce);
2065 uint8_t *payload = NULL;
2066 if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
2068 if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
2081 OCStackResult SetAclRownerId(const OicUuid_t* newROwner)
2083 OCStackResult ret = OC_STACK_ERROR;
2084 uint8_t *cborPayload = NULL;
2086 OicUuid_t prevId = {.id={0}};
2088 if(NULL == newROwner)
2090 ret = OC_STACK_INVALID_PARAM;
2094 ret = OC_STACK_NO_RESOURCE;
2097 if(newROwner && gAcl)
2099 memcpy(prevId.id, gAcl->rownerID.id, sizeof(prevId.id));
2100 memcpy(gAcl->rownerID.id, newROwner->id, sizeof(newROwner->id));
2102 ret = AclToCBORPayload(gAcl, &cborPayload, &size);
2103 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2105 ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size);
2106 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
2108 OICFree(cborPayload);
2114 OICFree(cborPayload);
2115 memcpy(gAcl->rownerID.id, prevId.id, sizeof(prevId.id));
2119 OCStackResult GetAclRownerId(OicUuid_t *rowneruuid)
2121 OCStackResult retVal = OC_STACK_ERROR;
2124 *rowneruuid = gAcl->rownerID;
2125 retVal = OC_STACK_OK;