[IOT-1354] Multiple APIs crashed instead of returning OC_STACK_INVALID_PARAM while...
[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 "cacommonutil.h"
9 #include "aclresource.h"
10 #include "ocpayloadcbor.h"
11 #include "payload_logging.h"
12
13 #define TAG "CLOUD-ACL-ID"
14
15 /**
16  * ACL Id parse from received response
17  *
18  * @param[in] ctx       context
19  * @param[out] data     data required to external application
20  * @param[in] response  peer response
21  * @return  OCStackResult application result
22  */
23 static OCStackResult getAclIdFromResponse(void *ctx, void **data, OCClientResponse *response)
24 {
25     OC_UNUSED(ctx);
26     if (NULL == response->payload)
27     {
28         OIC_LOG(ERROR, TAG, "Receive NULL payload");
29         return OC_STACK_INVALID_PARAM;
30     }
31
32     char *aclid = NULL;
33
34     if (!OCRepPayloadGetPropString((const OCRepPayload *)response->payload, OC_RSRVD_ACL_ID, &aclid))
35     {
36         OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_ACL_ID);
37         return OC_STACK_MALFORMED_RESPONSE;
38     }
39
40     OIC_LOG_V(INFO, TAG, "Received Acl id = %s", aclid);
41
42     *data = aclid;
43     return OC_STACK_OK;
44 }
45
46 /**
47  * ACL Id by device request received data handler
48  *
49  * @param[in] ctx       context
50  * @param[out] data     data required to external application
51  * @param[in] response  peer response
52  * @return  OCStackResult application result
53  */
54 static OCStackResult handleGetAclIdByDeviceResponse(void *ctx, void **data,
55                                                     OCClientResponse *response)
56 {
57     return getAclIdFromResponse(ctx, data, response);
58 }
59
60 /**
61  * ACL Id create request received data handler
62  *
63  * @param[in] ctx       context
64  * @param[out] data     data required to external application
65  * @param[in] response  peer response
66  * @return  OCStackResult application result
67  */
68 static OCStackResult handleAclIdCreateResponse(void *ctx, void **data, OCClientResponse *response)
69 {
70     return getAclIdFromResponse(ctx, data, response);
71 }
72
73 OCStackResult OCCloudGetAclIdByDevice(void* ctx,
74                                       const char *deviceId,
75                                       const OCDevAddr *endPoint,
76                                       OCCloudResponseCB callback)
77 {
78     char uri[MAX_URI_LENGTH] = { 0 };
79
80     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
81     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
82
83     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
84             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_DEVICE_ID, deviceId);
85
86     OCCallbackData cbData;
87     fillCallbackData(&cbData, ctx, callback, handleGetAclIdByDeviceResponse, NULL);
88
89     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
90                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
91 }
92
93 OCStackResult OCCloudAclIdCreate(void* ctx,
94                                  const char *ownerId,
95                                  const char *deviceId,
96                                  const OCDevAddr *endPoint,
97                                  OCCloudResponseCB callback)
98 {
99     char uri[MAX_URI_LENGTH] = { 0 };
100
101     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
102     VERIFY_NON_NULL_RET(ownerId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
103     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
104
105     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s&%s=%s", DEFAULT_PREFIX,
106             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL,
107             OC_RSRVD_OWNER_ID, ownerId, OC_RSRVD_DEVICE_ID, deviceId);
108
109     OCCallbackData cbData;
110     fillCallbackData(&cbData, ctx, callback, handleAclIdCreateResponse, NULL);
111
112     return OCDoResource(NULL, OC_REST_PUT, uri, NULL, NULL,
113                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
114 }
115
116 OCStackResult OCCloudAclIdDelete(void* ctx,
117                                  const char *aclId,
118                                  const OCDevAddr *endPoint,
119                                  OCCloudResponseCB callback)
120 {
121     char uri[MAX_URI_LENGTH]  = { 0 };
122
123     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
124     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
125
126     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
127             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_ACL_ID, aclId);
128
129     OCCallbackData cbData;
130     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
131
132     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
133                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
134 }
135
136 /**
137  * ACL Get Info received data handler
138  *
139  * @param[in] ctx       context
140  * @param[out] data     data required to external application
141  * @param[in] response  peer response
142  * @return  OCStackResult application result
143  */
144 static OCStackResult handleAclGetInfoResponse(void *ctx, void **data, OCClientResponse *response)
145 {
146     OCStackResult result = OC_STACK_OK;
147     uint8_t *cbor = NULL;
148     size_t size   = 0;
149
150     OC_UNUSED(ctx);
151     OC_UNUSED(data);
152
153     if (NULL == response->payload)
154     {
155         OIC_LOG(ERROR, TAG, "Receive NULL payload\n");
156         return OC_STACK_INVALID_PARAM;
157     }
158
159     result = OCConvertPayload(response->payload, &cbor, &size);
160     if (result != OC_STACK_OK)
161     {
162         OIC_LOG(ERROR, TAG, "Can't convert OCPayload to cbor");
163         goto exit;
164     }
165
166     OicSecAcl_t* acl = CBORPayloadToAcl2(cbor, size);
167     if (NULL == acl)
168     {
169         OIC_LOG(ERROR, TAG, "Can't parse CBOR payload");
170         goto exit;
171     }
172
173     result = InstallNewACL2(acl);
174     if (result != OC_STACK_OK)
175     {
176         OIC_LOG(ERROR, TAG, "Can't update ACL resource");
177     }
178
179 exit:
180     //can't delete acl because aces was added to gAcl
181     OICFree(cbor);
182     return result;
183 }
184
185 OCStackResult OCCloudAclIndividualGetInfo(void* ctx,
186                                           const char *aclId,
187                                           const OCDevAddr *endPoint,
188                                           OCCloudResponseCB callback)
189 {
190     char uri[MAX_URI_LENGTH]  = { 0 };
191
192     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
193     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
194
195     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
196             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
197
198     OCCallbackData cbData;
199     fillCallbackData(&cbData, ctx, callback, handleAclGetInfoResponse, NULL);
200
201     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
202                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
203 }
204
205 OCStackResult OCCloudAclIndividualUpdateAce(void* ctx,
206                                             const char *aclId,
207                                             const cloudAce_t *aces,
208                                             const OCDevAddr *endPoint,
209                                             OCCloudResponseCB callback)
210 {
211     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
212     char uri[MAX_URI_LENGTH]  = { 0 };
213
214     int i = 0, j = 0;
215
216     OCRepPayload **helperPayload  = NULL;
217     OCRepPayload **helperPayload2 = NULL;
218
219     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
220     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
221     VERIFY_NON_NULL_RET(aces, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
222
223     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
224             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
225
226     OCRepPayload *payload = OCRepPayloadCreate();
227     if (!payload)
228     {
229         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
230         goto no_memory;
231     }
232
233     int acllist_count = 0;
234     if (aces)
235     {
236         cloudAce_t *ace = (cloudAce_t *)&aces[acllist_count++];
237         while (ace->next)
238         {
239             ace = ace->next;
240             acllist_count++;
241         }
242     }
243
244     helperPayload = OICCalloc(acllist_count, sizeof(OCRepPayload *));
245     if (!helperPayload)
246     {
247         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload");
248         goto no_memory;
249     }
250
251     for (int i = 0; i < acllist_count; i++)
252     {
253         OCRepPayload *payload = OCRepPayloadCreate();
254         if (!payload)
255         {
256             OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]");
257             goto no_memory;
258         }
259         helperPayload[i] = payload;
260
261         const cloudAce_t *ace = &aces[i];
262
263         OCRepPayloadSetPropString(payload, OC_RSRVD_ACE_ID, ace->aceId);
264         OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)ace->subjectuuid.id);
265         OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
266         OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
267
268         int reslist_count = 0;
269         if (ace->resources)
270         {
271             OicSecRsrc_t *res = &ace->resources[reslist_count++];
272             while (res->next)
273             {
274                 res = res->next;
275                 reslist_count++;
276             }
277         }
278
279         helperPayload2 = OICCalloc(reslist_count, sizeof(OCRepPayload *));
280         if (!helperPayload2)
281         {
282             goto no_memory;
283         }
284
285         for (int j = 0; j < reslist_count; j++)
286         {
287             OCRepPayload *payload = OCRepPayloadCreate();
288             if (!payload)
289             {
290                 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
291                 goto no_memory;
292             }
293             helperPayload2[j] = payload;
294
295             const OicSecRsrc_t *res = &ace->resources[j];
296
297             OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href);
298
299             dimensions[0] = res->typeLen;
300             OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE,
301                                        (const char **)res->types, dimensions);
302
303             dimensions[0] = res->interfaceLen;
304             OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE,
305                                        (const char **)res->interfaces, dimensions);
306         }
307         dimensions[0] = reslist_count;
308         OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_RESOURCES,
309                 (const OCRepPayload **)helperPayload2, dimensions);
310     }
311     dimensions[0] = acllist_count;
312     OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ACCESS_CONTROL_LIST,
313             (const OCRepPayload **)helperPayload, dimensions);
314
315     OCCallbackData cbData;
316     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
317
318     OIC_LOG(DEBUG, TAG, "Next payload created:");
319     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)payload);
320
321     return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
322                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
323 no_memory:
324     if (helperPayload2)
325     {
326         for (int k = 0; k < j; k++) OCRepPayloadDestroy(helperPayload2[k]);
327         OICFree(helperPayload2);
328     }
329     if (helperPayload)
330     {
331         for (int k = 0; k < i; k++) OCRepPayloadDestroy(helperPayload[k]);
332         OICFree(helperPayload);
333     }
334     OCRepPayloadDestroy(payload);
335     return OC_STACK_NO_MEMORY;
336 }
337
338 OCStackResult OCCloudAclIndividualDelete(void* ctx,
339                                          const char *aclId,
340                                          const OCDevAddr *endPoint,
341                                          OCCloudResponseCB callback)
342 {
343     char uri[MAX_URI_LENGTH]  = { 0 };
344
345     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
346     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
347
348     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
349             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
350
351     OCCallbackData cbData;
352     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
353
354     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
355                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
356 }