Cloud ACE update
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / cloud / aclid.c
1 #include "utils.h"
2
3 #include "oic_malloc.h"
4 #include "logger.h"
5 #include "ocstack.h"
6 #include "ocpayload.h"
7 #include "pmutility.h"
8 #include "srmutility.h"
9 #include "cacommonutil.h"
10 #include "aclresource.h"
11 #include "ocpayloadcbor.h"
12 #include "payload_logging.h"
13 #include "utlist.h"
14
15 #define TAG "CLOUD-ACL-ID"
16
17 /**
18  * ACL Id parse from received response
19  *
20  * @param[in] ctx       context
21  * @param[out] data     data required to external application
22  * @param[in] response  peer response
23  * @return  OCStackResult application result
24  */
25 static OCStackResult getAclIdFromResponse(void *ctx, void **data, OCClientResponse *response)
26 {
27     OC_UNUSED(ctx);
28     if (NULL == response->payload)
29     {
30         OIC_LOG(ERROR, TAG, "Receive NULL payload");
31         return OC_STACK_INVALID_PARAM;
32     }
33
34     char *aclid = NULL;
35
36     if (!OCRepPayloadGetPropString((const OCRepPayload *)response->payload, OC_RSRVD_ACL_ID, &aclid))
37     {
38         OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_ACL_ID);
39         return OC_STACK_MALFORMED_RESPONSE;
40     }
41
42     OIC_LOG_V(INFO, TAG, "Received Acl id = %s", aclid);
43
44     *data = aclid;
45     return OC_STACK_OK;
46 }
47
48 /**
49  * ACL Id by device request received data handler
50  *
51  * @param[in] ctx       context
52  * @param[out] data     data required to external application
53  * @param[in] response  peer response
54  * @return  OCStackResult application result
55  */
56 static OCStackResult handleGetAclIdByDeviceResponse(void *ctx, void **data,
57                                                     OCClientResponse *response)
58 {
59     return getAclIdFromResponse(ctx, data, response);
60 }
61
62 /**
63  * ACL Id create request received data handler
64  *
65  * @param[in] ctx       context
66  * @param[out] data     data required to external application
67  * @param[in] response  peer response
68  * @return  OCStackResult application result
69  */
70 static OCStackResult handleAclIdCreateResponse(void *ctx, void **data, OCClientResponse *response)
71 {
72     return getAclIdFromResponse(ctx, data, response);
73 }
74
75 OCStackResult OCCloudGetAclIdByDevice(void* ctx,
76                                       const char *deviceId,
77                                       const OCDevAddr *endPoint,
78                                       OCCloudResponseCB callback)
79 {
80     char uri[MAX_URI_LENGTH] = { 0 };
81
82     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
83     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
84
85     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
86             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_DEVICE_ID, deviceId);
87
88     OCCallbackData cbData;
89     fillCallbackData(&cbData, ctx, callback, handleGetAclIdByDeviceResponse, NULL);
90
91     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
92                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
93 }
94
95 OCStackResult OCCloudAclIdCreate(void* ctx,
96                                  const char *ownerId,
97                                  const char *deviceId,
98                                  const OCDevAddr *endPoint,
99                                  OCCloudResponseCB callback)
100 {
101     char uri[MAX_URI_LENGTH] = { 0 };
102
103     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
104     VERIFY_NON_NULL_RET(ownerId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
105     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
106
107     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s&%s=%s", DEFAULT_PREFIX,
108             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL,
109             OC_RSRVD_OWNER_ID, ownerId, OC_RSRVD_DEVICE_ID, deviceId);
110
111     OCCallbackData cbData;
112     fillCallbackData(&cbData, ctx, callback, handleAclIdCreateResponse, NULL);
113
114     return OCDoResource(NULL, OC_REST_PUT, uri, NULL, NULL,
115                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
116 }
117
118 OCStackResult OCCloudAclIdDelete(void* ctx,
119                                  const char *aclId,
120                                  const OCDevAddr *endPoint,
121                                  OCCloudResponseCB callback)
122 {
123     char uri[MAX_URI_LENGTH]  = { 0 };
124
125     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
126     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
127
128     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
129             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_ACL_ID, aclId);
130
131     OCCallbackData cbData;
132     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
133
134     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
135                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
136 }
137
138 /**
139  * ACL Get Info received data handler
140  *
141  * @param[in] ctx       context
142  * @param[out] data     data required to external application
143  * @param[in] response  peer response
144  * @return  OCStackResult application result
145  */
146 static OCStackResult handleAclGetInfoResponse(void *ctx, void **data, OCClientResponse *response)
147 {
148     OCStackResult result = OC_STACK_OK;
149     uint8_t *cbor = NULL;
150     size_t size   = 0;
151
152     OC_UNUSED(ctx);
153     OC_UNUSED(data);
154
155     if (NULL == response->payload)
156     {
157         OIC_LOG(ERROR, TAG, "Receive NULL payload\n");
158         return OC_STACK_INVALID_PARAM;
159     }
160
161     result = OCConvertPayload(response->payload, &cbor, &size);
162     if (result != OC_STACK_OK)
163     {
164         OIC_LOG(ERROR, TAG, "Can't convert OCPayload to cbor");
165         goto exit;
166     }
167
168     OicSecAcl_t* acl = CBORPayloadToAcl2(cbor, size);
169     if (NULL == acl)
170     {
171         OIC_LOG(ERROR, TAG, "Can't parse CBOR payload");
172         goto exit;
173     }
174
175     printACL(acl);
176
177     result = InstallNewACL2(acl);
178     if (result != OC_STACK_OK)
179     {
180         OIC_LOG(ERROR, TAG, "Can't update ACL resource");
181     }
182
183     *data = acl;
184 exit:
185     OICFree(cbor);
186     return result;
187 }
188
189 OCStackResult OCCloudAclIndividualGetInfo(void* ctx,
190                                           const char *aclId,
191                                           const OCDevAddr *endPoint,
192                                           OCCloudResponseCB callback)
193 {
194     char uri[MAX_URI_LENGTH]  = { 0 };
195
196     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
197     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
198
199     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
200             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
201
202     OCCallbackData cbData;
203     fillCallbackData(&cbData, ctx, callback, handleAclGetInfoResponse, NULL);
204
205     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
206                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
207 }
208
209 OCStackResult OCCloudAclIndividualUpdateAce(void* ctx,
210                                             const char *aclId,
211                                             const cloudAce_t *aces,
212                                             const OCDevAddr *endPoint,
213                                             OCCloudResponseCB callback)
214 {
215     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
216     char uri[MAX_URI_LENGTH]  = { 0 };
217
218     int i = 0, j = 0;
219
220     OCRepPayload **helperPayload  = NULL;
221     OCRepPayload **helperPayload2 = NULL;
222
223     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
224     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
225     VERIFY_NON_NULL_RET(aces, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
226
227     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
228             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
229
230     OCRepPayload *payload = OCRepPayloadCreate();
231     if (!payload)
232     {
233         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
234         goto no_memory;
235     }
236
237     int acllist_count = 0;
238     //code below duplicates LL_COUNT, implemented in newer version of utlist.h
239     {
240         cloudAce_t *ace = (cloudAce_t*)aces;
241         while (ace)
242         {
243             ace = ace->next;
244             acllist_count++;
245         }
246     }
247
248     helperPayload = OICCalloc(acllist_count, sizeof(OCRepPayload *));
249     if (!helperPayload)
250     {
251         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload");
252         goto no_memory;
253     }
254
255     i = 0;
256     cloudAce_t *ace = NULL;
257
258     LL_FOREACH((cloudAce_t*)aces, ace)
259     {
260         OCRepPayload *payload = OCRepPayloadCreate();
261         if (!payload)
262         {
263             OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]");
264             goto no_memory;
265         }
266         helperPayload[i++] = payload;
267
268         char *uuid = NULL;
269         if (OC_STACK_OK != ConvertUuidToStr(&ace->subjectuuid, &uuid))
270         {
271             OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
272         }
273
274         OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)uuid);
275         OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
276         OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
277
278         OICFree(uuid);
279
280         int reslist_count = 0;
281         //code below duplicates LL_COUNT, implemented in newer version of utlist.h
282         {
283             OicSecRsrc_t *res = ace->resources;
284             while (res)
285             {
286                 res = res->next;
287                 reslist_count++;
288             }
289         }
290
291         helperPayload2 = OICCalloc(reslist_count, sizeof(OCRepPayload *));
292         if (!helperPayload2)
293         {
294             goto no_memory;
295         }
296
297         j = 0;
298         OicSecRsrc_t *res = NULL;
299
300         LL_FOREACH(ace->resources, res)
301         {
302             OCRepPayload *payload = OCRepPayloadCreate();
303             if (!payload)
304             {
305                 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload2[j]");
306                 goto no_memory;
307             }
308             helperPayload2[j++] = payload;
309
310             OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href);
311
312             dimensions[0] = res->typeLen;
313             OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE,
314                                        (const char **)res->types, dimensions);
315
316             dimensions[0] = res->interfaceLen;
317             OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE,
318                                        (const char **)res->interfaces, dimensions);
319         }
320         dimensions[0] = reslist_count;
321         OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_RESOURCES,
322                 (const OCRepPayload **)helperPayload2, dimensions);
323     }
324     dimensions[0] = acllist_count;
325     OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ACCESS_CONTROL_LIST,
326             (const OCRepPayload **)helperPayload, dimensions);
327
328     OCCallbackData cbData;
329     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
330
331     OIC_LOG(DEBUG, TAG, "Next payload created:");
332     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)payload);
333
334     return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
335                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
336 no_memory:
337     if (helperPayload2)
338     {
339         for (int k = 0; k < j; k++) OCRepPayloadDestroy(helperPayload2[k]);
340         OICFree(helperPayload2);
341     }
342     if (helperPayload)
343     {
344         for (int k = 0; k < i; k++) OCRepPayloadDestroy(helperPayload[k]);
345         OICFree(helperPayload);
346     }
347     OCRepPayloadDestroy(payload);
348     return OC_STACK_NO_MEMORY;
349 }
350
351 OCStackResult OCCloudAclIndividualUpdate(void* ctx,
352                                             const char *aclId,
353                                             const char *aceId,
354                                             const cloudAce_t *aces,
355                                             const OCDevAddr *endPoint,
356                                             OCCloudResponseCB callback)
357 {
358     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
359     char uri[MAX_URI_LENGTH]  = { 0 };
360
361     int i = 0, j = 0;
362
363     OCRepPayload **helperPayload  = NULL;
364     OCRepPayload **helperPayload2 = NULL;
365
366     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
367     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
368     VERIFY_NON_NULL_RET(aces, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
369
370     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s?%s=%s", DEFAULT_PREFIX,
371             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId,
372             OC_RSRVD_ACE_ID, aceId);
373
374     OCRepPayload *payload = OCRepPayloadCreate();
375     if (!payload)
376     {
377         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
378         goto no_memory;
379     }
380
381     int acllist_count = 1;
382
383     helperPayload = OICCalloc(acllist_count, sizeof(OCRepPayload *));
384     if (!helperPayload)
385     {
386         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload");
387         goto no_memory;
388     }
389
390     i = 0;
391     cloudAce_t *ace = NULL;
392
393     LL_FOREACH((cloudAce_t*)aces, ace)
394     {
395         OCRepPayload *payload = OCRepPayloadCreate();
396         if (!payload)
397         {
398             OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]");
399             goto no_memory;
400         }
401         helperPayload[i++] = payload;
402
403         char *uuid = NULL;
404         if (OC_STACK_OK != ConvertUuidToStr(&ace->subjectuuid, &uuid))
405         {
406             OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
407         }
408
409         OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)uuid);
410         OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
411         OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
412
413         OICFree(uuid);
414
415         int reslist_count = 0;
416         //code below duplicates LL_COUNT, implemented in newer version of utlist.h
417         {
418             OicSecRsrc_t *res = ace->resources;
419             while (res)
420             {
421                 res = res->next;
422                 reslist_count++;
423             }
424         }
425
426         helperPayload2 = OICCalloc(reslist_count, sizeof(OCRepPayload *));
427         if (!helperPayload2)
428         {
429             goto no_memory;
430         }
431
432         j = 0;
433         OicSecRsrc_t *res = NULL;
434
435         LL_FOREACH(ace->resources, res)
436         {
437             OCRepPayload *payload = OCRepPayloadCreate();
438             if (!payload)
439             {
440                 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload2[j]");
441                 goto no_memory;
442             }
443             helperPayload2[j++] = payload;
444
445             OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href);
446
447             dimensions[0] = res->typeLen;
448             OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE,
449                                        (const char **)res->types, dimensions);
450
451             dimensions[0] = res->interfaceLen;
452             OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE,
453                                        (const char **)res->interfaces, dimensions);
454         }
455         dimensions[0] = reslist_count;
456         OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_RESOURCES,
457                 (const OCRepPayload **)helperPayload2, dimensions);
458     }
459     dimensions[0] = acllist_count;
460     OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ACCESS_CONTROL_LIST,
461             (const OCRepPayload **)helperPayload, dimensions);
462
463     OCCallbackData cbData;
464     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
465
466     OIC_LOG(DEBUG, TAG, "Next payload created:");
467     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)payload);
468
469     return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
470                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
471 no_memory:
472     if (helperPayload2)
473     {
474         for (int k = 0; k < j; k++) OCRepPayloadDestroy(helperPayload2[k]);
475         OICFree(helperPayload2);
476     }
477     if (helperPayload)
478     {
479         for (int k = 0; k < i; k++) OCRepPayloadDestroy(helperPayload[k]);
480         OICFree(helperPayload);
481     }
482     OCRepPayloadDestroy(payload);
483     return OC_STACK_NO_MEMORY;
484 }
485
486
487
488 OCStackResult OCCloudAclIndividualDelete(void* ctx,
489                                          const char *aclId,
490                                          const OCDevAddr *endPoint,
491                                          OCCloudResponseCB callback)
492 {
493     char uri[MAX_URI_LENGTH]  = { 0 };
494
495     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
496     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
497
498     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
499             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
500
501     OCCallbackData cbData;
502     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
503
504     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
505                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
506 }
507
508 OCStackResult OCCloudAclIndividualDeleteAce(void* ctx,
509                                          const char *aclId,
510                                          const char *aceId,
511                                          const OCDevAddr *endPoint,
512                                          OCCloudResponseCB callback)
513 {
514     char uri[MAX_URI_LENGTH]  = { 0 };
515
516     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
517     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
518
519     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s?%s=%s", DEFAULT_PREFIX,
520             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId,
521             OC_RSRVD_ACE_ID, aceId);
522
523     OCCallbackData cbData;
524     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
525
526     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
527                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
528 }
529