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