Split cloudClient to Client & Server part
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / cloud / cloudWrapper.c
1 #include "logger.h"
2 #include "occloudprovisioning.h"
3 #include "oic_malloc.h"
4 #include "oic_string.h"
5 #include "srmutility.h"
6 #include "utlist.h"
7
8 #include "utils.h"
9
10 #define TAG "CLOUD-WRAPPER"
11
12 #define MAX_ID_LENGTH       (64)
13 #define MAX_STRING_LENGTH   (256)
14
15 #define UUID_EXAMPLE_1 "9cfbeb8e-5a1e-4d1c-9d01-2ae6fdb"
16 #define UUID_EXAMPLE_2 "123e4567-e89b-12d3-a456-4266554"
17 #define UUID_EXAMPLE_3 "987e6543-e21b-12d3-a456-4266554"
18 #define SUBJECT_ID_EXAMPLE "72616E64-5069-6E44-6576-557569643030"
19
20 #define ACL_ID_EXAMPLE "0f3d9f7fe5491d54077d"
21 #define ACE_ID_EXAMPLE "a0001"
22
23 #define ID_EXAMPLE_1   "78f98b4f25f21e2487e8"
24 #define ID_EXAMPLE_2   "6caa7009386290fd3681"
25
26 #define RESOURCE_URI_EXAMPLE "/a/light/0"
27 #define RESOURCE_TYPE_EXAMPLE "core.light"
28 #define INTERFACE_EXAMPLE "oic.if.baseline"
29
30 //in case of optional parameters absence should be sent NULL
31 #define OPTIONAL(str) (str[0] ? str : NULL)
32
33 static bool readOptional(const char* description)
34 {
35     if (NULL == description)
36     {
37         return false;
38     }
39
40     printf("Do you want to Enter %s (y/n):\n", description);
41     char choice = 0;
42
43     while(1)
44     {
45         scanf("%c", &choice);
46         getchar();
47
48         switch (choice)
49         {
50             case 'y': return true;
51             case 'n': return false;
52             default: printf("Wrong value entered. Please press 'y' or 'n'\n");
53         }
54     }
55     return false;
56 }
57
58 void readString(char* item, int length, const char* description, const char* example)
59 {
60     printf("Enter %s (f.e. %s):\n", description, example);
61     char template[8] = { 0 };
62     snprintf(template, sizeof(template), "%%%ds", length - 1);
63     scanf(template, item);
64     getchar();
65 }
66
67 /**
68  * Read user input (expect string value, but it is optional and can be skipped by user)
69  *
70  * @param[out] item           string item to fill
71  * @param[in] length          max allowed string length
72  * @param[in] description     item description
73  * @param[in] example         item example
74  */
75 static void readOptionalString(char* item, int length, const char* description, const char* example)
76 {
77     if (readOptional(description))
78     {
79         readString(item, length, description, example);
80     }
81 }
82
83 void readInteger(int* item, const char* description, const char* example)
84 {
85     printf("Enter %s (f.e. %s):\n", description, example);
86     scanf("%d", item);
87     getchar();
88 }
89
90 /**
91  * Read user input (expect array of strings)
92  *
93  * @param[out] list           array of strings structure
94  * @param[in] length          max allowed array item length
95  * @param[in] description     whole array description
96  * @param[in] example         array item example
97  */
98 static void readStringArray(stringArray_t *list, int length, const char* description, const char* example)
99 {
100     int i = 0;
101     int count = 0;
102     char hint[MAX_STRING_LENGTH] = { 0 };
103
104     snprintf(hint, sizeof(hint), "%s items count", description);
105     readInteger(&count, hint, "2");
106
107     char **item = NULL;
108
109     if (0 == count)
110     {
111         return;
112     }
113
114     item = OICCalloc(count, sizeof(char*));
115
116     if (NULL == item)
117     {
118         goto no_memory;
119     }
120
121     for (i = 0; i < count; i++)
122     {
123         item[i] = OICCalloc(length, sizeof(char));
124
125         if (NULL == item[i])
126         {
127             goto no_memory;
128         }
129
130         snprintf(hint, sizeof(hint), "%s %d item", description, i + 1);
131         readString(item[i], length, hint, example);
132     }
133     list->array  = item;
134     list->length = count;
135     return;
136
137 no_memory:
138     //free already allocated memory here
139     for (int k = 0; k < i; k++)
140     {
141         OICFree(item[k]);
142     }
143     OICFree(item);
144 }
145
146 /**
147  * Read user input (expect array of strings)
148  * It is optional and can be skipped by user.
149  *
150  * @param[out] list           array of strings structure
151  * @param[in] length          max allowed array item length
152  * @param[in] description     whole array description
153  * @param[in] example         array item example
154  */
155 static void readOptionalStringArray(stringArray_t *list, int length, const char* description, const char* example)
156 {
157     if (readOptional(description))
158     {
159         readStringArray(list, length, description, example);
160     }
161 }
162
163 bool readFile(const char *name, OCByteString *out)
164 {
165     FILE *file = NULL;
166     int length = 0;
167     uint8_t *buffer = NULL;
168     bool result = false;
169
170     //Open file
171     file = fopen(name, "rb");
172     if (!file)
173     {
174         OIC_LOG_V(ERROR, TAG, "Unable to open file %s", name);
175         return result;
176     }
177
178     //Get file length
179     if (fseek(file, 0, SEEK_END))
180     {
181         OIC_LOG(ERROR, TAG, "Failed to SEEK_END");
182         goto exit;
183     }
184
185     length = ftell(file);
186     if (length < 0)
187     {
188         OIC_LOG(ERROR, TAG, "Failed to ftell");
189         goto exit;
190     }
191
192     if (fseek(file, 0, SEEK_SET))
193     {
194         OIC_LOG(ERROR, TAG, "Failed to SEEK_SET");
195         goto exit;
196     }
197
198     //Allocate memory
199     buffer = (uint8_t *)malloc(length);
200     if (!buffer)
201     {
202         OIC_LOG(ERROR, TAG, "Failed to allocate buffer");
203         goto exit;
204     }
205
206     //Read file contents into buffer
207     size_t realLen = fread(buffer, length, 1, file);
208     if (realLen != (size_t)length)
209     {
210         OIC_LOG_V(ERROR, TAG, "Length mismatch: read %zu instead of %d bytes", realLen, length);
211         goto exit;
212     }
213
214     out->bytes = buffer;
215     out->len   = length;
216
217     result = true;
218 exit:
219     fclose(file);
220     return result;
221 }
222
223 /**
224  * Frees particular cloudAce object
225  *
226  * @param[in] ace   ace object to free
227  * */
228 static void freeCloudAce(cloudAce_t *ace)
229 {
230     OICFree(ace->aceId);
231
232     //Clean Resources
233     OicSecRsrc_t* rsrc = NULL;
234     OicSecRsrc_t* tmpRsrc = NULL;
235     LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
236     {
237         LL_DELETE(ace->resources, rsrc);
238         FreeRsrc(rsrc);
239     }
240
241     OICFree(ace);
242 }
243
244 /**
245  * Deletes cloudAce list
246  *
247  * @param[in] ace   aces list to delete
248  * */
249 static void deleteCloudAceList(cloudAce_t *aces)
250 {
251     cloudAce_t *ace = NULL;
252     cloudAce_t *tmpAce = NULL;
253     LL_FOREACH_SAFE(aces, ace, tmpAce)
254     {
255         LL_DELETE(aces, ace);
256         freeCloudAce(ace);
257     }
258 }
259
260 OCStackResult OCWrapperCertificateIssueRequest(const OCDevAddr *endPoint, OCCloudResponseCB callback)
261 {
262     return OCCloudCertificateIssueRequest(NULL, endPoint, callback);
263 }
264
265 OCStackResult OCWrapperGetCRL(const OCDevAddr *endPoint, OCCloudResponseCB callback)
266 {
267     return OCCloudGetCRL(NULL, endPoint, callback);
268 }
269
270 OCStackResult OCWrapperPostCRL(const OCDevAddr *endPoint, OCCloudResponseCB callback)
271 {
272     OCStackResult result = OC_STACK_ERROR;
273     OCByteString crlData = {0, 0};
274     char filename[64] = {0};
275     char thisUpdate[16] = { 0 };
276     char nextUpdate[16] = { 0 };
277     stringArray_t serialNumbers = {0, 0};
278
279     readString(thisUpdate, sizeof(thisUpdate), "Crl's thisUpdate value", "20160727000000");
280     readString(nextUpdate, sizeof(nextUpdate), "Crl's nextUpdate value", "20161027000000");
281     readOptionalStringArray(&serialNumbers, 16, "Revoked serial numbers", "1234");
282
283     if (NULL == serialNumbers.array)
284     {
285         readString(filename, sizeof(filename),
286                    "filename from which binary Crl in DER format will be read", "crl");
287
288         if (!readFile(filename, &crlData))
289         {
290             printf("Can't read crl from file %s\n", filename);
291             goto exit;
292         }
293     }
294     stringArray_t *rcsn = serialNumbers.array? &serialNumbers : NULL;
295     OCByteString *crl = crlData.bytes? &crlData : NULL;
296
297     result = OCCloudPostCRL(NULL, thisUpdate, nextUpdate, crl, rcsn,
298                             endPoint, callback);
299 exit:
300     clearStringArray(&serialNumbers);
301     OICFree(crlData.bytes);
302
303     return result;
304 }
305
306 OCStackResult OCWrapperAclIdGetByDevice(const OCDevAddr *endPoint, OCCloudResponseCB callback)
307 {
308     char di[MAX_ID_LENGTH] = { 0 };
309
310     readString(di, sizeof(di), "device id", UUID_EXAMPLE_1);
311
312     return OCCloudGetAclIdByDevice(NULL, di, endPoint, callback);
313 }
314
315 OCStackResult OCWrapperAclIdCreate(const OCDevAddr *endPoint, OCCloudResponseCB callback)
316 {
317     char oid[MAX_ID_LENGTH]  = { 0 };
318     char di[MAX_ID_LENGTH]   = { 0 };
319
320     readString(oid, sizeof(oid), "owner id", UUID_EXAMPLE_2);
321     readString(di, sizeof(di), "device id", UUID_EXAMPLE_1);
322
323     return OCCloudAclIdCreate(NULL, oid, di, endPoint, callback);
324 }
325
326 OCStackResult OCWrapperAclIdDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback)
327 {
328     char aclid[MAX_ID_LENGTH] = { 0 };
329
330     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
331
332     return OCCloudAclIdDelete(NULL, aclid, endPoint, callback);
333 }
334
335 OCStackResult OCWrapperAclIndividualGetInfo(const OCDevAddr *endPoint, OCCloudResponseCB callback)
336 {
337     char aclid[MAX_ID_LENGTH] = { 0 };
338
339     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
340
341     return OCCloudAclIndividualGetInfo(NULL, aclid, endPoint, callback);
342 }
343
344 OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloudResponseCB callback)
345 {
346     OCStackResult result = OC_STACK_NO_MEMORY;
347
348     char aclid[MAX_ID_LENGTH] = { 0 };
349     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
350
351     int acllist_count = 0;
352     readInteger(&acllist_count, "acl list count", "1");
353
354     cloudAce_t *aces = NULL;
355
356     for (int i = 0; i < acllist_count; i++)
357     {
358         cloudAce_t *ace = OICCalloc(1, sizeof(cloudAce_t));
359         if (!ace)
360         {
361             OIC_LOG(ERROR, TAG, "Can't allocate memory for ace");
362             goto exit;
363         }
364         LL_APPEND(aces, ace);
365
366         char aceid[MAX_ID_LENGTH] = { 0 };
367         char subjectuuid[MAX_ID_LENGTH] = { 0 };
368         int stype = 0;
369         int permission = 0;
370
371         readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE);
372         do
373         {
374             readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE);
375         } while (OC_STACK_OK != ConvertStrToUuid(subjectuuid, &ace->subjectuuid));
376
377         readInteger(&stype, "subject type", "0 â€“ Device, 1 â€“ User, 2 - Group");
378         readInteger(&permission, "permission", "6");
379
380         ace->aceId = OICStrdup(aceid);
381         ace->stype = stype;
382         ace->permission = permission;
383
384         int reslist_count = 0;
385         readInteger(&reslist_count, "resources list count", "1");
386
387         for (int i = 0; i < reslist_count; i++)
388         {
389             OicSecRsrc_t *res = OICCalloc(1, sizeof(OicSecRsrc_t));
390             if (!res)
391             {
392                 OIC_LOG(ERROR, TAG, "Can't allocate memory for res");
393                 goto exit;
394             }
395             LL_APPEND(ace->resources, res);
396
397             char href[32] = { 0 };
398             readString(href, sizeof(href), "href", RESOURCE_URI_EXAMPLE);
399
400             stringArray_t rt = {0, 0};
401             readStringArray(&rt, MAX_ID_LENGTH, "resource type", RESOURCE_TYPE_EXAMPLE);
402
403             stringArray_t _if = {0, 0};
404             readStringArray(&_if, MAX_ID_LENGTH, "interface", INTERFACE_EXAMPLE);
405
406             res->href = OICStrdup(href);
407             res->types = rt.array;
408             res->typeLen = rt.length;
409             res->interfaces = _if.array;
410             res->interfaceLen = _if.length;
411         }
412     }
413
414     result = OCCloudAclIndividualUpdateAce(NULL, aclid, aces, endPoint, callback);
415 exit:
416     deleteCloudAceList(aces);
417     return result;
418 }
419
420 OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback)
421 {
422     char aclid[MAX_ID_LENGTH] = { 0 };
423
424     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
425
426     return OCCloudAclIndividualDelete(NULL, aclid, endPoint, callback);
427 }
428
429 OCStackResult OCWrapperAclCreateGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
430 {
431     char gtype[16] = { 0 };
432     char gmid[MAX_ID_LENGTH] = { 0 };
433
434     readString(gtype, sizeof(gtype), "Group type value", "Public");
435     readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2);
436
437     return OCCloudAclCreateGroup(NULL, gtype, OPTIONAL(gmid), endPoint, callback);
438 }
439
440 OCStackResult OCWrapperAclFindMyGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
441 {
442     char mid[MAX_ID_LENGTH]  = { 0 };
443
444     readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2);
445
446     return OCCloudAclFindMyGroup(NULL, OPTIONAL(mid), endPoint, callback);
447 }
448
449 OCStackResult OCWrapperAclDeleteGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
450 {
451     char gid[MAX_ID_LENGTH]  = { 0 };
452     char gmid[MAX_ID_LENGTH] = { 0 };
453
454     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
455
456     readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2);
457
458     return OCCloudAclDeleteGroup(NULL, gid, OPTIONAL(gmid), endPoint, callback);
459 }
460
461 OCStackResult OCWrapperAclJoinToInvitedGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
462 {
463     char gid[MAX_ID_LENGTH]  = { 0 };
464
465     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
466
467     return OCCloudAclJoinToInvitedGroup(NULL, gid, endPoint, callback);
468 }
469
470 OCStackResult OCWrapperAclObserveGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
471 {
472     char gid[MAX_ID_LENGTH]  = { 0 };
473
474     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
475
476     return OCCloudAclObserveGroup(NULL, gid, endPoint, callback);
477 }
478
479 OCStackResult OCWrapperAclShareDeviceIntoGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
480 {
481     OCStackResult result = OC_STACK_NO_MEMORY;
482     char gid[MAX_ID_LENGTH]  = { 0 };
483     stringArray_t midlist = {0,0};
484     stringArray_t dilist = {0,0};
485
486     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
487
488     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
489
490     readStringArray(&dilist, MAX_ID_LENGTH, "device list", UUID_EXAMPLE_1);
491
492     result = OCCloudAclShareDeviceIntoGroup(NULL, gid, &midlist, &dilist, endPoint, callback);
493
494     clearStringArray(&midlist);
495     clearStringArray(&dilist);
496
497     return result;
498 }
499
500 OCStackResult OCWrapperAclDeleteDeviceFromGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
501 {
502     OCStackResult result = OC_STACK_NO_MEMORY;
503     char gid[MAX_ID_LENGTH]  = { 0 };
504     stringArray_t midlist = {0,0};
505     stringArray_t dilist = {0,0};
506
507     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
508
509     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
510
511     readStringArray(&dilist, MAX_ID_LENGTH, "device list", UUID_EXAMPLE_1);
512
513     result = OCCloudAclDeleteDeviceFromGroup(NULL, gid, &midlist, &dilist, endPoint, callback);
514
515     clearStringArray(&midlist);
516     clearStringArray(&dilist);
517
518     return result;
519 }
520
521 OCStackResult OCWrapperAclGroupGetInfo(const OCDevAddr *endPoint, OCCloudResponseCB callback)
522 {
523     char gid[MAX_ID_LENGTH]  = { 0 };
524     char mid[MAX_ID_LENGTH]  = { 0 };
525
526     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
527
528     readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2);
529
530     return OCCloudAclGroupGetInfo(NULL, gid, OPTIONAL(mid), endPoint, callback);
531 }
532
533 OCStackResult OCWrapperAclInviteUser(const OCDevAddr *endPoint, OCCloudResponseCB callback)
534 {
535     OCStackResult result = OC_STACK_NO_MEMORY;
536     char uid[MAX_ID_LENGTH]  = { 0 };
537     stringArray_t midlist = {0,0};
538     stringArray_t gidlist = {0,0};
539
540     readOptionalString(uid, sizeof(uid), "user id value", UUID_EXAMPLE_2);
541
542     readStringArray(&gidlist, MAX_ID_LENGTH, "group id list", UUID_EXAMPLE_1);
543
544     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
545
546     result = OCCloudAclInviteUser(NULL, OPTIONAL(uid), &gidlist, &midlist, endPoint, callback);
547
548     clearStringArray(&midlist);
549     clearStringArray(&gidlist);
550
551     return result;
552 }
553
554 OCStackResult OCWrapperAclGetInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
555 {
556     char uid[MAX_ID_LENGTH]  = { 0 };
557
558     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
559
560     return OCCloudAclGetInvitation(NULL, OPTIONAL(uid), endPoint, callback);
561 }
562
563 OCStackResult OCWrapperAclDeleteInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
564 {
565     char uid[MAX_ID_LENGTH]  = { 0 };
566     char gid[MAX_ID_LENGTH]  = { 0 };
567
568     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
569     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
570
571     return OCCloudAclDeleteInvitation(NULL, OPTIONAL(uid), gid, endPoint, callback);
572 }
573
574 OCStackResult OCWrapperAclCancelInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
575 {
576     char uid[MAX_ID_LENGTH]  = { 0 };
577     char gid[MAX_ID_LENGTH]  = { 0 };
578     char mid[MAX_ID_LENGTH]  = { 0 };
579
580     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
581
582     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
583     readString(mid, sizeof(mid), "member id value", ID_EXAMPLE_1);
584
585     return OCCloudAclCancelInvitation(NULL, OPTIONAL(uid), gid, mid, endPoint, callback);
586 }
587
588 OCStackResult OCWrapperAclPolicyCheck(const OCDevAddr *endPoint, OCCloudResponseCB callback)
589 {
590     char sid[MAX_ID_LENGTH] = { 0 };
591     char di[MAX_ID_LENGTH]  = { 0 };
592     char rm[16]  = { 0 };
593     char user_uri[32] = { 0 };
594
595     readString(sid, sizeof(sid), "subject id", UUID_EXAMPLE_1);
596     readString(di, sizeof(di), "device id", UUID_EXAMPLE_2);
597     readString(rm, sizeof(rm), "request method", "GET or POST or DELETE");
598     readString(user_uri, sizeof(user_uri), "request uri", RESOURCE_URI_EXAMPLE);
599
600     return OCCloudAclPolicyCheck(NULL, sid, di, rm, user_uri, endPoint, callback);
601 }