1 /* *****************************************************************
3 * Copyright 2016 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 * *****************************************************************/
22 #include "oic_malloc.h"
25 #include "ocpayload.h"
26 #include "pmutility.h"
27 #include "cacommonutil.h"
28 #include "aclresource.h"
29 #include "ocpayloadcbor.h"
30 #include "payload_logging.h"
32 #include "securevirtualresourcetypes.h"
34 #define TAG "OIC_CLOUD_ACL_ID"
36 /* Although this is already implemented in srmutility.h, we can't include the header file,
37 * because of "redefined VERIFY_NON_NULL"
39 OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid);
42 * ACL Id parse from received response
44 * @param[in] ctx context
45 * @param[out] data data required to external application
46 * @param[in] response peer response
47 * @return OCStackResult application result
49 static OCStackResult getAclIdFromResponse(void *ctx, void **data, OCClientResponse *response)
52 if (NULL == response->payload)
54 OIC_LOG(ERROR, TAG, "Receive NULL payload");
55 return OC_STACK_INVALID_PARAM;
60 if (!OCRepPayloadGetPropString((const OCRepPayload *)response->payload, OC_RSRVD_ACL_ID, &aclid))
62 OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_ACL_ID);
63 return OC_STACK_MALFORMED_RESPONSE;
66 OIC_LOG_V(INFO, TAG, "Received Acl id = %s", aclid);
73 * ACL Id by device request received data handler
75 * @param[in] ctx context
76 * @param[out] data data required to external application
77 * @param[in] response peer response
78 * @return OCStackResult application result
80 static OCStackResult handleGetAclIdByDeviceResponse(void *ctx, void **data,
81 OCClientResponse *response)
83 return getAclIdFromResponse(ctx, data, response);
87 * ACL Id create request received data handler
89 * @param[in] ctx context
90 * @param[out] data data required to external application
91 * @param[in] response peer response
92 * @return OCStackResult application result
94 static OCStackResult handleAclIdCreateResponse(void *ctx, void **data, OCClientResponse *response)
96 return getAclIdFromResponse(ctx, data, response);
99 OCStackResult OCCloudGetAclIdByDevice(void* ctx,
100 const char *deviceId,
101 const OCDevAddr *endPoint,
102 OCCloudResponseCB callback)
104 char uri[MAX_URI_LENGTH] = { 0 };
106 VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
107 VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
109 snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
110 endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_DEVICE_ID, deviceId);
112 OCCallbackData cbData;
113 fillCallbackData(&cbData, ctx, callback, handleGetAclIdByDeviceResponse, NULL);
115 return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
116 CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
119 OCStackResult OCCloudAclIdCreate(void* ctx,
121 const char *deviceId,
122 const OCDevAddr *endPoint,
123 OCCloudResponseCB callback)
125 char uri[MAX_URI_LENGTH] = { 0 };
127 VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
128 VERIFY_NON_NULL_RET(ownerId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
129 VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
131 snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s&%s=%s", DEFAULT_PREFIX,
132 endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL,
133 OC_RSRVD_OWNER_ID, ownerId, OC_RSRVD_DEVICE_ID, deviceId);
135 OCCallbackData cbData;
136 fillCallbackData(&cbData, ctx, callback, handleAclIdCreateResponse, NULL);
138 return OCDoResource(NULL, OC_REST_PUT, uri, NULL, NULL,
139 CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
142 OCStackResult OCCloudAclIdDelete(void* ctx,
144 const OCDevAddr *endPoint,
145 OCCloudResponseCB callback)
147 char uri[MAX_URI_LENGTH] = { 0 };
149 VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
150 VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
152 snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
153 endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_ACL_ID, aclId);
155 OCCallbackData cbData;
156 fillCallbackData(&cbData, ctx, callback, NULL, NULL);
158 return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
159 CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
163 * ACL Get Info received data handler
165 * @param[in] ctx context
166 * @param[out] data data required to external application
167 * @param[in] response peer response
168 * @return OCStackResult application result
170 static OCStackResult handleAclGetInfoResponse(void *ctx, void **data, OCClientResponse *response)
172 OCStackResult result = OC_STACK_OK;
173 uint8_t *cbor = NULL;
179 if (NULL == response->payload)
181 OIC_LOG(ERROR, TAG, "Receive NULL payload\n");
182 return OC_STACK_INVALID_PARAM;
185 result = OCConvertPayload(response->payload, &cbor, &size);
186 if (result != OC_STACK_OK)
188 OIC_LOG(ERROR, TAG, "Can't convert OCPayload to cbor");
192 OicSecAcl_t* acl = CBORPayloadToAcl2(cbor, size);
195 OIC_LOG(ERROR, TAG, "Can't parse CBOR payload");
201 result = InstallACL(acl);
202 if (result != OC_STACK_OK)
204 OIC_LOG(ERROR, TAG, "Can't update ACL resource");
213 OCStackResult OCCloudAclIndividualGetInfo(void* ctx,
215 const OCDevAddr *endPoint,
216 OCCloudResponseCB callback)
218 char uri[MAX_URI_LENGTH] = { 0 };
220 VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
221 VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
223 snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
224 endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
226 OCCallbackData cbData;
227 fillCallbackData(&cbData, ctx, callback, handleAclGetInfoResponse, NULL);
229 return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
230 CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
233 OCStackResult OCCloudAclIndividualUpdateAce(void* ctx,
235 const cloudAce_t *aces,
236 const OCDevAddr *endPoint,
237 OCCloudResponseCB callback)
239 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
240 char uri[MAX_URI_LENGTH] = { 0 };
244 OCRepPayload **helperPayload = NULL;
245 OCRepPayload **helperPayload2 = NULL;
247 VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
248 VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
249 VERIFY_NON_NULL_RET(aces, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
251 snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
252 endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
254 OCRepPayload *payload = OCRepPayloadCreate();
257 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
261 int acllist_count = 0;
262 //code below duplicates LL_COUNT, implemented in newer version of utlist.h
264 cloudAce_t *ace = (cloudAce_t*)aces;
272 helperPayload = OICCalloc(acllist_count, sizeof(OCRepPayload *));
275 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload");
280 cloudAce_t *ace = NULL;
282 LL_FOREACH((cloudAce_t*)aces, ace)
284 OCRepPayload *payload = OCRepPayloadCreate();
287 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]");
290 helperPayload[i++] = payload;
293 if (OC_STACK_OK != ConvertUuidToStr(&ace->subjectuuid, &uuid))
295 OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
298 OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)uuid);
299 OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
300 OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
304 int reslist_count = 0;
305 //code below duplicates LL_COUNT, implemented in newer version of utlist.h
307 OicSecRsrc_t *res = ace->resources;
315 helperPayload2 = OICCalloc(reslist_count, sizeof(OCRepPayload *));
322 OicSecRsrc_t *res = NULL;
324 LL_FOREACH(ace->resources, res)
326 OCRepPayload *payload = OCRepPayloadCreate();
329 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload2[j]");
332 helperPayload2[j++] = payload;
334 OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href);
336 dimensions[0] = res->typeLen;
337 OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE,
338 (const char **)res->types, dimensions);
340 dimensions[0] = res->interfaceLen;
341 OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE,
342 (const char **)res->interfaces, dimensions);
344 dimensions[0] = reslist_count;
345 OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_RESOURCES,
346 (const OCRepPayload **)helperPayload2, dimensions);
348 dimensions[0] = acllist_count;
349 OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ACCESS_CONTROL_LIST,
350 (const OCRepPayload **)helperPayload, dimensions);
352 OCCallbackData cbData;
353 fillCallbackData(&cbData, ctx, callback, NULL, NULL);
355 OIC_LOG(DEBUG, TAG, "Next payload created:");
356 OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)payload);
358 return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
359 CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
363 for (int k = 0; k < j; k++) OCRepPayloadDestroy(helperPayload2[k]);
364 OICFree(helperPayload2);
368 for (int k = 0; k < i; k++) OCRepPayloadDestroy(helperPayload[k]);
369 OICFree(helperPayload);
371 OCRepPayloadDestroy(payload);
372 return OC_STACK_NO_MEMORY;
375 OCStackResult OCCloudAclIndividualUpdate(void* ctx,
378 const cloudAce_t *aces,
379 const OCDevAddr *endPoint,
380 OCCloudResponseCB callback)
382 size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
383 char uri[MAX_URI_LENGTH] = { 0 };
387 OCRepPayload **helperPayload = NULL;
388 OCRepPayload **helperPayload2 = NULL;
390 VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
391 VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
392 VERIFY_NON_NULL_RET(aces, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
394 snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s?%s=%s", DEFAULT_PREFIX,
395 endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId,
396 OC_RSRVD_ACE_ID, aceId);
398 OCRepPayload *payload = OCRepPayloadCreate();
401 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
405 int acllist_count = 1;
407 helperPayload = OICCalloc(acllist_count, sizeof(OCRepPayload *));
410 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload");
415 cloudAce_t *ace = NULL;
417 LL_FOREACH((cloudAce_t*)aces, ace)
419 OCRepPayload *payload = OCRepPayloadCreate();
422 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]");
425 helperPayload[i++] = payload;
428 if (OC_STACK_OK != ConvertUuidToStr(&ace->subjectuuid, &uuid))
430 OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
433 OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)uuid);
434 OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
435 OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
439 int reslist_count = 0;
440 //code below duplicates LL_COUNT, implemented in newer version of utlist.h
442 OicSecRsrc_t *res = ace->resources;
450 helperPayload2 = OICCalloc(reslist_count, sizeof(OCRepPayload *));
457 OicSecRsrc_t *res = NULL;
459 LL_FOREACH(ace->resources, res)
461 OCRepPayload *payload = OCRepPayloadCreate();
464 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload2[j]");
467 helperPayload2[j++] = payload;
469 OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href);
471 dimensions[0] = res->typeLen;
472 OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE,
473 (const char **)res->types, dimensions);
475 dimensions[0] = res->interfaceLen;
476 OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE,
477 (const char **)res->interfaces, dimensions);
479 dimensions[0] = reslist_count;
480 OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_RESOURCES,
481 (const OCRepPayload **)helperPayload2, dimensions);
483 dimensions[0] = acllist_count;
484 OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ACCESS_CONTROL_LIST,
485 (const OCRepPayload **)helperPayload, dimensions);
487 OCCallbackData cbData;
488 fillCallbackData(&cbData, ctx, callback, NULL, NULL);
490 OIC_LOG(DEBUG, TAG, "Next payload created:");
491 OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)payload);
493 return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
494 CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
498 for (int k = 0; k < j; k++) OCRepPayloadDestroy(helperPayload2[k]);
499 OICFree(helperPayload2);
503 for (int k = 0; k < i; k++) OCRepPayloadDestroy(helperPayload[k]);
504 OICFree(helperPayload);
506 OCRepPayloadDestroy(payload);
507 return OC_STACK_NO_MEMORY;
512 OCStackResult OCCloudAclIndividualDelete(void* ctx,
514 const OCDevAddr *endPoint,
515 OCCloudResponseCB callback)
517 char uri[MAX_URI_LENGTH] = { 0 };
519 VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
520 VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
522 snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
523 endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
525 OCCallbackData cbData;
526 fillCallbackData(&cbData, ctx, callback, NULL, NULL);
528 return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
529 CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
532 OCStackResult OCCloudAclIndividualDeleteAce(void* ctx,
535 const OCDevAddr *endPoint,
536 OCCloudResponseCB callback)
538 char uri[MAX_URI_LENGTH] = { 0 };
540 VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
541 VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
543 snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s?%s=%s", DEFAULT_PREFIX,
544 endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId,
545 OC_RSRVD_ACE_ID, aceId);
547 OCCallbackData cbData;
548 fillCallbackData(&cbData, ctx, callback, NULL, NULL);
550 return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
551 CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
554 OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid)
556 if (NULL == uuid || NULL == strUuid || NULL != *strUuid)
558 OIC_LOG(ERROR, TAG, "ConvertUuidToStr : Invalid param");
559 return OC_STACK_INVALID_PARAM;
564 const size_t urnBufSize = (UUID_LENGTH * 2) + 4 + 1;
565 char *convertedUrn = (char*)OICCalloc(urnBufSize, sizeof(char));
566 VERIFY_NON_NULL(convertedUrn, TAG, "OICCalloc() is failed(convertedUrn)");
568 for (uuidIdx = 0, urnIdx = 0; uuidIdx < UUID_LENGTH && urnIdx < urnBufSize;
569 uuidIdx++, urnIdx += 2)
571 // canonical format for UUID has '8-4-4-4-12'
572 if (4 == uuidIdx || 6 == uuidIdx || 8 == uuidIdx || 10 == uuidIdx)
574 snprintf(convertedUrn + urnIdx, 2, "%c", '-');
577 snprintf(convertedUrn + urnIdx, 3, "%02x", (uint8_t)(uuid->id[uuidIdx]));
579 convertedUrn[urnBufSize - 1] = '\0';
581 *strUuid = convertedUrn;