acf96ac38fe9699db95abb6fa54f8b8e78351bfd
[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 "ocprovisioningmanager.h"
31
32 #include "utils.h"
33 #include "cloudAuth.h"
34 #include "cloudCommon.h"
35 #include "cloudWrapper.h"
36 #include "cloudDiscovery.h"
37
38 #ifdef __unix__
39 #include <unistd.h> //for unlink
40 #endif
41
42 #define TAG "cloudCommon"
43
44 #define DEFAULT_HOST            "10.113.68.85"//"127.0.0.1"
45 #define DEFAULT_PORT            OC_MULTICAST_PORT
46 #define DEFAULT_AUTH_PROVIDER   "github"
47 #define DEFAULT_DB_FILE         "./cloud.dat"
48 #define DEFAULT_RESPONSE_WAIT_TIME (10 * 1000000) //10s
49
50 #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"
51
52 #define CLIENT_ONLY(mode)       if (OC_SERVER == mode) { wrongRequest(); break; }
53
54 static bool fExit = false;
55
56 static ca_thread_pool_t g_threadPoolHandle = NULL;
57 static OCDevAddr endPoint;
58 static char token[1024] = "";
59 static char authProvider[1024] = DEFAULT_AUTH_PROVIDER;
60 static char *fname = DEFAULT_DB_FILE;
61 static uint64_t timeout;
62 static uint16_t g_credId = 0;
63
64 static ca_cond cond;
65 static ca_mutex mutex;
66
67 typedef enum {
68     SIGN_UP       = 1,
69     SIGN_IN       = 2,
70     SIGN_OUT      = 3,
71
72     HOST          = 4,
73     PORT          = 5,
74     DB_FILE       = 6,
75     AUTH_PROVIDER = 7,
76     USE_RSA = 8,
77     SAVE_TRUST_CERT = 9,
78     USE_SECURE_CONN = 10,
79
80     DISCOVERY     = 13,
81     GET           = 14,
82     PUT           = 15,
83     POST          = 16,
84
85     CSR_SIGN      = 19,
86
87     CRL_GET       = 20,
88     CRL_POST      = 21,
89
90     ACL_ID_CREATE = 30,
91     ACL_ID_GET_BY_DEVICE = 31,
92     ACL_ID_DELETE = 32,
93
94     ACL_INDIVIDUAL_GET_INFO = 40,
95     ACL_INDIVIDUAL_UPDATE_ACE = 41,
96     ACL_INDIVIDUAL_DELETE = 42,
97
98     ACL_GROUP_CREATE = 50,
99     ACL_GROUP_FIND   = 51,
100     ACL_GROUP_JOIN   = 52,
101     ACL_GROUP_OBSERVE= 53,
102     ACL_GROUP_DELETE = 54,
103
104     ACL_GROUP_SHARE_DEVICE  = 60,
105     ACL_GROUP_DELETE_DEVICE  = 61,
106     ACL_GROUP_GET_INFO  = 62,
107
108     ACL_POLICY_CHECK_REQUEST = 70,
109
110     ACL_GROUP_INVITE_USER = 80,
111     ACL_GROUP_GET_INVITE  = 81,
112     ACL_GROUP_DELETE_INVITE  = 82,
113     ACL_GROUP_CANCEL_INVITE  = 83,
114
115     EXIT          = 99
116 }CloudRequest;
117
118 static void printMenu(OCMode mode)
119 {
120     char *title = "Client";
121     if (OC_SERVER == mode)
122     {
123         title = "Server";
124     }
125     printf("************************************************************\n");
126     printf("****************** Cloud %s Requests *******************\n", title);
127     printf("************************************************************\n");
128     printf("** AUTHORIZATION\n");
129     printf("** %d - Sign Up request\n", SIGN_UP);
130     printf("** %d - Sign In request\n", SIGN_IN);
131     printf("** %d - Sign Out request\n", SIGN_OUT);
132
133     printf("** SETTINGS \n");
134     printf("** %d - Change default host\n", HOST);
135     printf("** %d - Change default port\n", PORT);
136     printf("** %d - Change default database filename\n", DB_FILE);
137     printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
138     printf("** %d - Change TLS cipher suite to RSA\n", USE_RSA);
139     printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
140     printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
141
142     if (OC_CLIENT == mode)
143     {
144         printf("** DISCOVERY\n");
145         printf("** %d - Start Discovery\n", DISCOVERY);
146         printf("** %d - Get Request\n", GET);
147         printf("** %d - Put Request\n", PUT);
148         printf("** %d - Post Request\n", POST);
149     }
150
151     printf("** CERTIFICATE REQUEST\n");
152     printf("** %d - Certificate Request\n", CSR_SIGN);
153
154     printf("** CRL\n");
155     printf("** %d - CRL GET Request\n", CRL_GET);
156     printf("** %d - CRL POST Request\n", CRL_POST);
157
158     printf("** ACL MANAGER\n");
159     printf("** %d - ACL id create Request\n", ACL_ID_CREATE);
160     printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE);
161     printf("** %d - ACL id delete Request\n", ACL_ID_DELETE);
162
163     printf("** ACL INDIVIDUAL\n");
164     printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
165     printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
166     printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
167
168     printf("** ACL GROUP MANAGER\n");
169     printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
170     printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND);
171     printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN);
172     printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE);
173     printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE);
174
175     printf("** ACL INDIVIDUAL GROUP\n");
176     printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE);
177     printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE);
178     printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO);
179
180     printf("** ACL POLICY ENFORCEMENT\n");
181     printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST);
182
183     printf("** ACL MEMBER INVITATION\n");
184     printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER);
185     printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE);
186     printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE);
187     printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
188
189     printf("** EXIT\n");
190     printf("** %d - Exit cloud %s\n\n", EXIT, title);
191     printf("************************************************************\n");
192
193     printf(">> Enter Menu number:\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 static OCStackResult saveTrustCert(void)
227 {
228     OCStackResult res = OC_STACK_ERROR;
229     OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
230
231     ByteArray trustCertChainArray = {0, 0};
232     const char *filename = "rootca.crt";
233
234     if (!readFile(filename, (OCByteString *)&trustCertChainArray))
235     {
236         OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
237         return OC_STACK_ERROR;
238     }
239     OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
240
241     res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
242
243     if(OC_STACK_OK != res)
244     {
245         OIC_LOG(ERROR, TAG, "OCSaveTrustCertChainBin API error");
246         return res;
247     }
248     OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
249
250     return res;
251 }
252
253 static void wrongRequest()
254 {
255     printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
256 }
257
258 static void userRequests(void *data)
259 {
260     if (NULL == data)
261     {
262         OIC_LOG(ERROR, TAG, "Received NULL data");
263         return;
264     }
265
266     OCMode mode = *(OCMode*)data;
267
268     memset(&endPoint, 0, sizeof(endPoint));
269     strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
270     endPoint.port = DEFAULT_PORT;
271
272     mutex = ca_mutex_new();
273     cond = ca_cond_new();
274
275     while (false == fExit)
276     {
277         OCStackResult res = OC_STACK_ERROR;
278         timeout = DEFAULT_RESPONSE_WAIT_TIME;
279         //startup report
280         printf("-----------------------------------------------------------\n");
281         printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port);
282         printf("via auth provider: %s\n", authProvider);
283         printf("srv file: %s\n", fname);
284         printf("CoAP prefix: %s\n", DEFAULT_PREFIX);
285         printf("-----------------------------------------------------------\n");
286
287         printMenu(mode);
288
289         int request = 0;
290         scanf("%d", &request);
291
292         switch (request)
293         {
294         case SIGN_UP:
295             if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)))
296             {
297                 printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK);
298             }
299             readString(token, sizeof(token), "auth token", "check link above");
300             res = CloudSignUp(&endPoint, authProvider, token);
301             break;
302         case SIGN_IN:
303             res = CloudSignIn(&endPoint);
304             break;
305         case SIGN_OUT:
306             res = CloudSignOut(&endPoint);
307             break;
308         case HOST:
309             readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
310             break;
311         case PORT:
312         {
313             char example[8];
314             snprintf(example, sizeof(example), "%d", DEFAULT_PORT);
315             int tmp = 0;
316             readInteger(&tmp, "port number", example);
317             endPoint.port = tmp;
318         }
319         break;
320         case CRL_GET:
321             res = OCWrapperGetCRL(&endPoint, handleCB);
322             break;
323         case CRL_POST:
324             res = OCWrapperPostCRL(&endPoint, handleCB);
325             break;
326         case ACL_GROUP_CREATE:
327             res = OCWrapperAclCreateGroup(&endPoint, handleCB);
328             break;
329         case ACL_GROUP_FIND:
330             res = OCWrapperAclFindMyGroup(&endPoint, handleCB);
331             break;
332         case ACL_GROUP_DELETE:
333             res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
334             break;
335         case ACL_GROUP_JOIN:
336             res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB);
337             break;
338         case ACL_GROUP_OBSERVE:
339             res = OCWrapperAclObserveGroup(&endPoint, handleCB);
340             break;
341         case ACL_GROUP_SHARE_DEVICE:
342             res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB);
343             break;
344         case ACL_GROUP_DELETE_DEVICE:
345             res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB);
346             break;
347         case ACL_GROUP_GET_INFO:
348             res = OCWrapperAclGroupGetInfo(&endPoint, handleCB);
349             break;
350         case ACL_GROUP_INVITE_USER:
351             res = OCWrapperAclInviteUser(&endPoint, handleCB);
352             break;
353         case ACL_GROUP_GET_INVITE:
354             res = OCWrapperAclGetInvitation(&endPoint, handleCB);
355             break;
356         case ACL_GROUP_DELETE_INVITE:
357             res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
358             break;
359         case ACL_GROUP_CANCEL_INVITE:
360             res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
361             break;
362         case ACL_POLICY_CHECK_REQUEST:
363             res = OCWrapperAclPolicyCheck(&endPoint, handleCB);
364             break;
365         case ACL_ID_GET_BY_DEVICE:
366             res = OCWrapperAclIdGetByDevice(&endPoint, handleCB);
367             break;
368         case ACL_ID_CREATE:
369             res = OCWrapperAclIdCreate(&endPoint, handleCB);
370             break;
371         case ACL_ID_DELETE:
372             res = OCWrapperAclIdDelete(&endPoint, handleCB);
373             break;
374         case ACL_INDIVIDUAL_GET_INFO:
375             res = OCWrapperAclIndividualGetInfo(&endPoint, handleCB);
376             break;
377         case ACL_INDIVIDUAL_UPDATE_ACE:
378             res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
379             break;
380         case ACL_INDIVIDUAL_DELETE:
381             res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
382             break;
383         case CSR_SIGN:
384             res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
385             break;
386         case DISCOVERY:
387             CLIENT_ONLY(mode);
388             res = InitDiscovery();
389             break;
390         case GET:
391             CLIENT_ONLY(mode);
392             res = InitRequest(OC_REST_GET);
393             break;
394         case PUT:
395             CLIENT_ONLY(mode);
396             res= InitRequest(OC_REST_PUT);
397             break;
398         case POST:
399             CLIENT_ONLY(mode);
400             res= InitRequest(OC_REST_POST);
401             break;
402         case USE_RSA:
403             CASelectCipherSuite(0x35, CA_ADAPTER_TCP);
404             break;
405         case SAVE_TRUST_CERT:
406             saveTrustCert();
407             break;
408         case USE_SECURE_CONN:
409         {
410             int tmp = 0;
411             readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
412             setCoapPrefix(0 == tmp ? false : true);
413         }
414             break;
415         case EXIT:
416             ca_mutex_free(mutex);
417             ca_cond_free(cond);
418             fExit = true;
419             break;
420         default:
421             wrongRequest();
422             break;
423         }
424
425         //if requests were sent then wait response
426         if (res == OC_STACK_OK)
427         {
428             ca_mutex_lock(mutex);
429             ca_cond_wait_for(cond, mutex, timeout);
430             ca_mutex_unlock(mutex);
431         }
432     }
433 }
434
435 FILE* server_fopen(const char *path, const char *mode)
436 {
437     OC_UNUSED(path);
438     return fopen(fname, mode);
439 }
440
441 /**
442  * Check file accessibility
443  *
444  * @param[in] name        file path
445  * @return true           if check was successful
446  */
447 static bool checkConfig(const char *name)
448 {
449     FILE* file = fopen(name, "rb");
450
451     if (file)
452     {
453         fclose(file);
454         return true;
455     }
456     return false;
457 }
458
459 static void printUsage(char *name)
460 {
461     printf("Wrong arguments count!\n");
462     printf("Usage : %s <database_filename>\n", name);
463     printf("Examples : 1) %s 2) %s cloud.dat\n", name, name);
464 }
465
466 bool parseCommandLineArguments(int argc, char *argv[])
467 {
468     bool result = true;
469     if (2 == argc)
470     {
471         fname = argv[1];
472
473         if (!checkConfig(fname))
474         {
475             OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname);
476             result = false;
477         }
478     }
479     else if (argc > 2)
480     {
481         printUsage(argv[0]);
482         result = false;
483     }
484     return result;
485 }
486
487 OCStackResult initPersistentStorage()
488 {
489     //Initialize Persistent Storage for SVR database
490     static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
491
492     return OCRegisterPersistentStorageHandler(&ps);
493 }
494
495 OCStackResult startRequestsThread(OCMode *mode)
496 {
497     CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle);
498     if (CA_STATUS_OK != res)
499     {
500         OIC_LOG(ERROR, TAG, "thread pool initialize error.");
501         return res;
502     }
503
504     res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode);
505     if (CA_STATUS_OK != res)
506     {
507         OIC_LOG(ERROR, TAG, "thread pool add task error.");
508         ca_thread_pool_free(g_threadPoolHandle);
509     }
510     return res;
511 }
512
513 OCStackResult initProcess(OCMode mode)
514 {
515     return OCInit(NULL, 0, mode);
516 }
517
518 void startProcess()
519 {
520     while(false == fExit)
521     {
522         if (OCProcess() != OC_STACK_OK)
523         {
524             OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
525             break;
526         }
527     }
528
529     if (OCStop() != OC_STACK_OK)
530     {
531         OIC_LOG(ERROR, TAG, "OCStop process error\n");
532     }
533 }
534
535 void freeThreadResources()
536 {
537     if (g_threadPoolHandle)
538     {
539         ca_thread_pool_free(g_threadPoolHandle);
540     }
541 }