RC3 svace fix (cloudClient + crlresource.c)
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / cloud / cloudCommon.c
1 //******************************************************************
2 //
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "ocstack.h"
25 #include "logger.h"
26 #include "camutex.h"
27 #include "cathreadpool.h"
28 #include "ocpayload.h"
29 #include "payload_logging.h"
30 #include "aclresource.h"
31 #include "crlresource.h"
32 #include "ocprovisioningmanager.h"
33
34 #include "utils.h"
35 #include "cloudAuth.h"
36 #include "cloudCommon.h"
37 #include "cloudWrapper.h"
38 #include "cloudDiscovery.h"
39
40 #ifdef __unix__
41 #include <unistd.h> //for unlink
42 #endif
43
44 #define TAG "cloudCommon"
45
46 #define DEFAULT_HOST            "10.113.68.85"//"127.0.0.1"
47 #define DEFAULT_PORT            OC_MULTICAST_PORT
48 #define DEFAULT_AUTH_PROVIDER   "github"
49 #define DEFAULT_DB_FILE         "./cloud.dat"
50 #define DEFAULT_RESPONSE_WAIT_TIME (10 * 1000000) //10s
51
52 #define GITHUB_AUTH_LINK        "https://github.com/login?return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dea9c18f540323b0213d0%26redirect_uri%3Dhttp%253A%252F%252Fwww.example.com%252Foauth_callback%252F"
53
54 #define CLIENT_ONLY(mode)       if (OC_SERVER == (mode)) { wrongRequest(); sendDataToServer = false; break; }
55
56 static bool fExit = false;
57
58 static ca_thread_pool_t g_threadPoolHandle = NULL;
59 static OCDevAddr endPoint;
60 static char token[1024] = "";
61 static char authProvider[1024] = DEFAULT_AUTH_PROVIDER;
62 static char *fname = DEFAULT_DB_FILE;
63 static uint64_t timeout;
64 static uint16_t g_credId = 0;
65
66 static ca_cond cond;
67 static ca_mutex mutex;
68
69 typedef enum {
70     SIGN_UP       = 1,
71     SIGN_IN       = 2,
72     SIGN_OUT      = 3,
73
74     HOST          = 4,
75     PORT          = 5,
76     DB_FILE       = 6,
77     AUTH_PROVIDER = 7,
78     USE_RSA = 8,
79     SAVE_TRUST_CERT = 9,
80     USE_SECURE_CONN = 10,
81
82     DISCOVERY     = 13,
83     GET           = 14,
84     PUT           = 15,
85     POST          = 16,
86
87     CSR_SIGN      = 19,
88
89     CRL_GET       = 20,
90     CRL_POST      = 21,
91
92     ACL_ID_CREATE = 30,
93     ACL_ID_GET_BY_DEVICE = 31,
94     ACL_ID_DELETE = 32,
95
96     ACL_INDIVIDUAL_GET_INFO = 40,
97     ACL_INDIVIDUAL_UPDATE_ACE = 41,
98     ACL_INDIVIDUAL_DELETE = 42,
99
100     ACL_GROUP_CREATE = 50,
101     ACL_GROUP_FIND   = 51,
102     ACL_GROUP_JOIN   = 52,
103     ACL_GROUP_OBSERVE= 53,
104     ACL_GROUP_DELETE = 54,
105
106     ACL_GROUP_SHARE_DEVICE  = 60,
107     ACL_GROUP_DELETE_DEVICE  = 61,
108     ACL_GROUP_GET_INFO  = 62,
109
110     ACL_POLICY_CHECK_REQUEST = 70,
111
112     ACL_GROUP_INVITE_USER = 80,
113     ACL_GROUP_GET_INVITE  = 81,
114     ACL_GROUP_DELETE_INVITE  = 82,
115     ACL_GROUP_CANCEL_INVITE  = 83,
116
117     EXIT          = 99
118 }CloudRequest;
119
120 static void printMenu(OCMode mode)
121 {
122     char *title = "Client";
123     if (OC_SERVER == mode)
124     {
125         title = "Server";
126     }
127     printf("************************************************************\n");
128     printf("****************** Cloud %s Requests *******************\n", title);
129     printf("************************************************************\n");
130     printf("** AUTHORIZATION\n");
131     printf("** %d - Sign Up request\n", SIGN_UP);
132     printf("** %d - Sign In request\n", SIGN_IN);
133     printf("** %d - Sign Out request\n", SIGN_OUT);
134
135     printf("** SETTINGS \n");
136     printf("** %d - Change default host\n", HOST);
137     printf("** %d - Change default port\n", PORT);
138     printf("** %d - Change default database filename\n", DB_FILE);
139     printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
140     printf("** %d - Change TLS cipher suite to RSA\n", USE_RSA);
141     printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
142     printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
143
144     if (OC_CLIENT == mode)
145     {
146         printf("** DISCOVERY\n");
147         printf("** %d - Start Discovery\n", DISCOVERY);
148         printf("** %d - Get Request\n", GET);
149         printf("** %d - Put Request\n", PUT);
150         printf("** %d - Post Request\n", POST);
151     }
152
153     printf("** CERTIFICATE REQUEST\n");
154     printf("** %d - Certificate Request\n", CSR_SIGN);
155
156     printf("** CRL\n");
157     printf("** %d - CRL GET Request\n", CRL_GET);
158     printf("** %d - CRL POST Request\n", CRL_POST);
159
160     printf("** ACL MANAGER\n");
161     printf("** %d - ACL id create Request\n", ACL_ID_CREATE);
162     printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE);
163     printf("** %d - ACL id delete Request\n", ACL_ID_DELETE);
164
165     printf("** ACL INDIVIDUAL\n");
166     printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
167     printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
168     printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
169
170     printf("** ACL GROUP MANAGER\n");
171     printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
172     printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND);
173     printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN);
174     printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE);
175     printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE);
176
177     printf("** ACL INDIVIDUAL GROUP\n");
178     printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE);
179     printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE);
180     printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO);
181
182     printf("** ACL POLICY ENFORCEMENT\n");
183     printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST);
184
185     printf("** ACL MEMBER INVITATION\n");
186     printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER);
187     printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE);
188     printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE);
189     printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
190
191     printf("** EXIT\n");
192     printf("** %d - Exit cloud %s\n", EXIT, title);
193     printf("************************************************************\n");
194 }
195
196 void unlockMenu(void *data)
197 {
198     OICFree(data);
199
200     if (!fExit)
201     {
202         ca_mutex_lock(mutex);
203         ca_cond_signal(cond);
204         ca_mutex_unlock(mutex);
205     }
206 }
207
208 /**
209  * This is default callback to all requests
210  * Used to sync with main menu
211  *
212  * @param[in] ctx          context
213  * @param[in] result       result
214  * @param[in] data         data
215  */
216 static void handleCB(void* ctx, OCStackResult result, void* data)
217 {
218     OC_UNUSED(ctx);
219     OC_UNUSED(data);
220
221     OIC_LOG_V(INFO, TAG, "%s: Received result = %d", __func__, result);
222
223     unlockMenu(NULL);
224 }
225
226 /**
227  * This function prints Acl id and calls default callback function handleCB()
228  *
229  * @param[in] ctx          context
230  * @param[in] result       result
231  * @param[in] aclId        acl id
232  */
233 static void handleAclIdCB(void* ctx, OCStackResult result, void* aclId)
234 {
235     OIC_LOG_V(INFO, TAG, "Received Acl id = %s", (char *)aclId);
236     handleCB(ctx, result, aclId);
237     OICFree(aclId);
238 }
239
240 /**
241  * This function prints group id and calls default callback function handleCB()
242  *
243  * @param[in] ctx          context
244  * @param[in] result       result
245  * @param[in] groupId      group id
246  */
247 static void handleAclCreateGroupCB(void* ctx, OCStackResult result, void* groupId)
248 {
249     OIC_LOG_V(INFO, TAG, "Received gid = %s", (char *)groupId);
250     handleCB(ctx, result, groupId);
251     OICFree(groupId);
252 }
253
254 /**
255  * This function prints group policy and calls default callback function handleCB()
256  *
257  * @param[in] ctx          context
258  * @param[in] result       result
259  * @param[in] gp           group policy
260  */
261 static void handleAclPolicyCheckCB(void* ctx, OCStackResult result, void* gp)
262 {
263     OIC_LOG_V(INFO, TAG, "Received gp = %s", (char *)gp);
264     handleCB(ctx, result, gp);
265     OICFree(gp);
266 }
267
268 /**
269  * This function prints received acl and calls default callback function handleCB()
270  *
271  * @param[in] ctx          context
272  * @param[in] result       result
273  * @param[in] acl          acl
274  */
275 static void handleAclIndividualGetInfoCB(void* ctx, OCStackResult result, void* acl)
276 {
277     printACL((OicSecAcl_t* )acl);
278     handleCB(ctx, result, acl);
279     //can't delete acl here because its ACE's were added to gAcl
280     //TODO: changes in aclresources.c required to fix that
281 }
282
283 /**
284  * This function prints received group id list and calls default callback function handleCB()
285  *
286  * @param[in] ctx          context
287  * @param[in] result       result
288  * @param[in] gidList      group id list
289  */
290 static void handleAclFindMyGroupCB(void* ctx, OCStackResult result, void* gidList)
291 {
292     printStringArray((stringArray_t *)gidList);
293     handleCB(ctx, result, gidList);
294     clearStringArray((stringArray_t *)gidList);
295 }
296
297 /**
298  * This function prints received acl and calls default callback function handleCB()
299  *
300  * @param[in] ctx          context
301  * @param[in] result       result
302  * @param[in] crl          crl
303  */
304 static void handleGetCrlCB(void* ctx, OCStackResult result, void* crl)
305 {
306     printCrl((OicSecCrl_t *)crl);
307     handleCB(ctx, result, crl);
308     DeleteCrl((OicSecCrl_t *)crl);
309 }
310
311 /**
312  * This function prints received invitation response and calls default callback function handleCB()
313  *
314  * @param[in] ctx          context
315  * @param[in] result       result
316  * @param[in] invite       invitation response (it has inviteResponse_t* type)
317  */
318 static void handleAclGetInvitationCB(void* ctx, OCStackResult result, void* invite)
319 {
320     printInviteResponse((inviteResponse_t *)invite);
321     handleCB(ctx, result, invite);
322     clearInviteResponse((inviteResponse_t *)invite);
323     OICFree(invite);
324 }
325
326 static OCStackResult saveTrustCert(void)
327 {
328     OCStackResult res = OC_STACK_ERROR;
329     OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
330
331     ByteArray trustCertChainArray = {0, 0};
332     const char *filename = "rootca.crt";
333
334     if (!readFile(filename, (OCByteString *)&trustCertChainArray))
335     {
336         OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
337         return OC_STACK_ERROR;
338     }
339     OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
340
341     res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
342
343     if (OC_STACK_OK != res)
344     {
345         OIC_LOG(ERROR, TAG, "OCSaveTrustCertChain API error");
346     }
347     else
348     {
349         OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
350     }
351     OICFree(trustCertChainArray.data);
352
353     return res;
354 }
355
356 static void wrongRequest()
357 {
358     printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
359 }
360
361 static void userRequests(void *data)
362 {
363     if (NULL == data)
364     {
365         OIC_LOG(ERROR, TAG, "Received NULL data");
366         return;
367     }
368
369     OCMode mode = *(OCMode*)data;
370
371     memset(&endPoint, 0, sizeof(endPoint));
372     strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
373     endPoint.port = DEFAULT_PORT;
374
375     mutex = ca_mutex_new();
376     cond = ca_cond_new();
377
378     while (false == fExit)
379     {
380         OCStackResult res = OC_STACK_ERROR;
381         bool sendDataToServer = true;
382         timeout = DEFAULT_RESPONSE_WAIT_TIME;
383         //startup report
384         printf("-----------------------------------------------------------\n");
385         printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port);
386         printf("via auth provider: %s\n", authProvider);
387         printf("srv file: %s\n", fname);
388         printf("CoAP prefix: %s\n", DEFAULT_PREFIX);
389         printf("-----------------------------------------------------------\n");
390
391         printMenu(mode);
392
393         int request = 0;
394         readInteger(&request, "Menu number", "see above");
395
396         switch (request)
397         {
398         case SIGN_UP:
399             if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)))
400             {
401                 printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK);
402             }
403             readString(token, sizeof(token), "auth token", "check link above");
404             res = CloudSignUp(&endPoint, authProvider, token);
405             break;
406         case SIGN_IN:
407             res = CloudSignIn(&endPoint);
408             break;
409         case SIGN_OUT:
410             res = CloudSignOut(&endPoint);
411             break;
412         case HOST:
413             readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
414             sendDataToServer = false;
415             break;
416         case PORT:
417         {
418             char example[8];
419             snprintf(example, sizeof(example), "%d", DEFAULT_PORT);
420             int tmp = 0;
421             readInteger(&tmp, "port number", example);
422             endPoint.port = tmp;
423             sendDataToServer = false;
424         }
425         break;
426         case CRL_GET:
427             res = OCWrapperGetCRL(&endPoint, handleGetCrlCB);
428             break;
429         case CRL_POST:
430             res = OCWrapperPostCRL(&endPoint, handleCB);
431             break;
432         case ACL_GROUP_CREATE:
433             res = OCWrapperAclCreateGroup(&endPoint, handleAclCreateGroupCB);
434             break;
435         case ACL_GROUP_FIND:
436             res = OCWrapperAclFindMyGroup(&endPoint, handleAclFindMyGroupCB);
437             break;
438         case ACL_GROUP_DELETE:
439             res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
440             break;
441         case ACL_GROUP_JOIN:
442             res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB);
443             break;
444         case ACL_GROUP_OBSERVE:
445             res = OCWrapperAclObserveGroup(&endPoint, handleCB);
446             break;
447         case ACL_GROUP_SHARE_DEVICE:
448             res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB);
449             break;
450         case ACL_GROUP_DELETE_DEVICE:
451             res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB);
452             break;
453         case ACL_GROUP_GET_INFO:
454             res = OCWrapperAclGroupGetInfo(&endPoint, handleCB);
455             break;
456         case ACL_GROUP_INVITE_USER:
457             res = OCWrapperAclInviteUser(&endPoint, handleCB);
458             break;
459         case ACL_GROUP_GET_INVITE:
460             res = OCWrapperAclGetInvitation(&endPoint, handleAclGetInvitationCB);
461             break;
462         case ACL_GROUP_DELETE_INVITE:
463             res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
464             break;
465         case ACL_GROUP_CANCEL_INVITE:
466             res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
467             break;
468         case ACL_POLICY_CHECK_REQUEST:
469             res = OCWrapperAclPolicyCheck(&endPoint, handleAclPolicyCheckCB);
470             break;
471         case ACL_ID_GET_BY_DEVICE:
472             res = OCWrapperAclIdGetByDevice(&endPoint, handleAclIdCB);
473             break;
474         case ACL_ID_CREATE:
475             res = OCWrapperAclIdCreate(&endPoint, handleAclIdCB);
476             break;
477         case ACL_ID_DELETE:
478             res = OCWrapperAclIdDelete(&endPoint, handleCB);
479             break;
480         case ACL_INDIVIDUAL_GET_INFO:
481             res = OCWrapperAclIndividualGetInfo(&endPoint, handleAclIndividualGetInfoCB);
482             break;
483         case ACL_INDIVIDUAL_UPDATE_ACE:
484             res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
485             break;
486         case ACL_INDIVIDUAL_DELETE:
487             res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
488             break;
489         case CSR_SIGN:
490             res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
491             break;
492         case DISCOVERY:
493             CLIENT_ONLY(mode);
494             res = InitDiscovery();
495             break;
496         case GET:
497             CLIENT_ONLY(mode);
498             res = InitRequest(OC_REST_GET);
499             break;
500         case PUT:
501             CLIENT_ONLY(mode);
502             res= InitRequest(OC_REST_PUT);
503             break;
504         case POST:
505             CLIENT_ONLY(mode);
506             res= InitRequest(OC_REST_POST);
507             break;
508         case USE_RSA:
509             CASelectCipherSuite(0x35, CA_ADAPTER_TCP);
510             sendDataToServer = false;
511             break;
512         case SAVE_TRUST_CERT:
513             saveTrustCert();
514             sendDataToServer = false;
515             break;
516         case USE_SECURE_CONN:
517         {
518             int tmp = 0;
519             readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
520             setCoapPrefix(0 == tmp ? false : true);
521             sendDataToServer = false;
522         }
523             break;
524         case EXIT:
525             ca_mutex_free(mutex);
526             ca_cond_free(cond);
527             fExit = true;
528             sendDataToServer = false;
529             break;
530         default:
531             wrongRequest();
532             sendDataToServer = false;
533             break;
534         }
535
536         //if requests were sent then wait response
537         if (sendDataToServer)
538         {
539             if (OC_STACK_OK == res)
540             {
541                 ca_mutex_lock(mutex);
542                 ca_cond_wait_for(cond, mutex, timeout);
543                 ca_mutex_unlock(mutex);
544             }
545             else
546             {
547                 OIC_LOG_V(ERROR, TAG, "Request returned an error %d", res);
548             }
549         }
550     }
551 }
552
553 FILE* server_fopen(const char *path, const char *mode)
554 {
555     OC_UNUSED(path);
556     return fopen(fname, mode);
557 }
558
559 /**
560  * Check file accessibility
561  *
562  * @param[in] name        file path
563  * @return true           if check was successful
564  */
565 static bool checkConfig(const char *name)
566 {
567     FILE* file = fopen(name, "rb");
568
569     if (file)
570     {
571         fclose(file);
572         return true;
573     }
574     return false;
575 }
576
577 static void printUsage(char *name)
578 {
579     printf("Wrong arguments count!\n");
580     printf("Usage : %s <database_filename>\n", name);
581     printf("Examples : 1) %s 2) %s cloud.dat\n", name, name);
582 }
583
584 bool parseCommandLineArguments(int argc, char *argv[])
585 {
586     bool result = true;
587     if (2 == argc)
588     {
589         fname = argv[1];
590
591         if (!checkConfig(fname))
592         {
593             OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname);
594             result = false;
595         }
596     }
597     else if (argc > 2)
598     {
599         printUsage(argv[0]);
600         result = false;
601     }
602     return result;
603 }
604
605 OCStackResult initPersistentStorage()
606 {
607     //Initialize Persistent Storage for SVR database
608     static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
609
610     return OCRegisterPersistentStorageHandler(&ps);
611 }
612
613 OCStackResult startRequestsThread(OCMode *mode)
614 {
615     CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle);
616     if (CA_STATUS_OK != res)
617     {
618         OIC_LOG(ERROR, TAG, "thread pool initialize error.");
619         return res;
620     }
621
622     res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode);
623     if (CA_STATUS_OK != res)
624     {
625         OIC_LOG(ERROR, TAG, "thread pool add task error.");
626         ca_thread_pool_free(g_threadPoolHandle);
627     }
628     return res;
629 }
630
631 OCStackResult initProcess(OCMode mode)
632 {
633     return OCInit(NULL, 0, mode);
634 }
635
636 void startProcess()
637 {
638     while(false == fExit)
639     {
640         if (OCProcess() != OC_STACK_OK)
641         {
642             OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
643             break;
644         }
645     }
646
647     if (OCStop() != OC_STACK_OK)
648     {
649         OIC_LOG(ERROR, TAG, "OCStop process error\n");
650     }
651 }
652
653 void freeThreadResources()
654 {
655     if (g_threadPoolHandle)
656     {
657         ca_thread_pool_free(g_threadPoolHandle);
658     }
659 }