1 //******************************************************************
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
28 #include "cathreadpool.h"
29 #include "ocpayload.h"
30 #include "payload_logging.h"
31 #include "aclresource.h"
32 #include "crlresource.h"
33 #include "ocprovisioningmanager.h"
34 #include "casecurityinterface.h"
35 #include "mbedtls/ssl_ciphersuites.h"
36 #include "pkix_interface.h"
37 #include "../hw_emul/hw_interface.h"
40 #include "cloudAuth.h"
41 #include "cloudCommon.h"
42 #include "cloudWrapper.h"
43 #include "cloudDiscovery.h"
46 #include <unistd.h> //for unlink
49 #define TAG "cloudCommon"
51 #define DEFAULT_HOST "10.113.68.85"//"127.0.0.1"
52 #define DEFAULT_PORT OC_MULTICAST_PORT
53 #define DEFAULT_AUTH_PROVIDER "github"
54 #define DEFAULT_DB_FILE "./cloud.dat"
55 #define DEFAULT_RESPONSE_WAIT_TIME (10 * 1000000) //10s
57 #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"
59 #define CLIENT_ONLY(mode) if (OC_SERVER == (mode)) { wrongRequest(); sendDataToServer = false; break; }
61 static bool fExit = false;
63 static ca_thread_pool_t g_threadPoolHandle = NULL;
64 static OCDevAddr endPoint;
65 static char token[1024] = "";
66 static char authProvider[1024] = DEFAULT_AUTH_PROVIDER;
67 static char *fname = DEFAULT_DB_FILE;
68 static uint64_t timeout;
69 static uint16_t g_credId = 0;
72 static oc_mutex mutex;
86 CONFIG_SELF_OWNERSHIP = 11,
87 SECURE_STORAGE_HW_EMULATION = 12,
100 ACL_ID_GET_BY_DEVICE = 31,
103 ACL_INDIVIDUAL_GET_INFO = 40,
104 ACL_INDIVIDUAL_UPDATE_ACE = 41,
105 ACL_INDIVIDUAL_UPDATE = 42,
106 ACL_INDIVIDUAL_DELETE = 43,
107 ACL_INDIVIDUAL_DELETE_ACE = 44,
109 ACL_GROUP_CREATE = 50,
112 ACL_GROUP_OBSERVE= 53,
113 ACL_GROUP_DELETE = 54,
115 ACL_GROUP_SHARE_DEVICE = 60,
116 ACL_GROUP_DELETE_DEVICE = 61,
117 ACL_GROUP_GET_INFO = 62,
119 ACL_POLICY_CHECK_REQUEST = 70,
121 ACL_GROUP_INVITE_USER = 80,
122 ACL_GROUP_GET_INVITE = 81,
123 ACL_GROUP_DELETE_INVITE = 82,
124 ACL_GROUP_CANCEL_INVITE = 83,
129 static void printMenu(OCMode mode)
131 char *title = "Client";
132 if (OC_SERVER == mode)
136 printf("************************************************************\n");
137 printf("****************** Cloud %s Requests *******************\n", title);
138 printf("************************************************************\n");
139 printf("** AUTHORIZATION\n");
140 printf("** %d - Sign Up request\n", SIGN_UP);
141 printf("** %d - Sign In request\n", SIGN_IN);
142 printf("** %d - Sign Out request\n", SIGN_OUT);
144 printf("** SETTINGS \n");
145 printf("** %d - Change default host\n", HOST);
146 printf("** %d - Change default port\n", PORT);
147 printf("** %d - Change default database filename\n", DB_FILE);
148 printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
149 printf("** %d - Change TLS cipher suite (ECDSA/RSA)\n", USE_RSA);
150 printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
151 printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
152 printf("** %d - Configure SVRdb as Self-OwnerShip\n", CONFIG_SELF_OWNERSHIP);
153 printf("** %d - Configure Secure Storage HW Emulation\n", SECURE_STORAGE_HW_EMULATION);
155 if (OC_CLIENT == mode)
157 printf("** DISCOVERY\n");
158 printf("** %d - Start Discovery\n", DISCOVERY);
159 printf("** %d - Get Request\n", GET);
160 printf("** %d - Put Request\n", PUT);
161 printf("** %d - Post Request\n", POST);
164 printf("** CERTIFICATE REQUEST\n");
165 printf("** %d - Certificate Request\n", CSR_SIGN);
168 printf("** %d - CRL GET Request\n", CRL_GET);
169 printf("** %d - CRL POST Request\n", CRL_POST);
171 printf("** ACL MANAGER\n");
172 printf("** %d - ACL id create Request\n", ACL_ID_CREATE);
173 printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE);
174 printf("** %d - ACL id delete Request\n", ACL_ID_DELETE);
176 printf("** ACL INDIVIDUAL\n");
177 printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
178 printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
179 printf("** %d - ACL individual update Request\n", ACL_INDIVIDUAL_UPDATE);
180 printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
181 printf("** %d - ACL individual delete ACE Request\n", ACL_INDIVIDUAL_DELETE_ACE);
183 printf("** ACL GROUP MANAGER\n");
184 printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
185 printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND);
186 printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN);
187 printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE);
188 printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE);
190 printf("** ACL INDIVIDUAL GROUP\n");
191 printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE);
192 printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE);
193 printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO);
195 printf("** ACL POLICY ENFORCEMENT\n");
196 printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST);
198 printf("** ACL MEMBER INVITATION\n");
199 printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER);
200 printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE);
201 printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE);
202 printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
205 printf("** %d - Exit cloud %s\n", EXIT, title);
206 printf("************************************************************\n");
209 void unlockMenu(void *data)
215 oc_mutex_lock(mutex);
216 oc_cond_signal(cond);
217 oc_mutex_unlock(mutex);
222 * This is default callback to all requests
223 * Used to sync with main menu
225 * @param[in] ctx context
226 * @param[in] result result
227 * @param[in] data data
229 static void handleCB(void* ctx, OCStackResult result, void* data)
234 OIC_LOG_V(INFO, TAG, "%s: Received result = %d", __func__, result);
240 * This function prints Acl id and calls default callback function handleCB()
242 * @param[in] ctx context
243 * @param[in] result result
244 * @param[in] aclId acl id
246 static void handleAclIdCB(void* ctx, OCStackResult result, void* aclId)
248 OIC_LOG_V(INFO, TAG, "Received Acl id = %s", (char *)aclId);
249 handleCB(ctx, result, aclId);
254 * This function prints group id and calls default callback function handleCB()
256 * @param[in] ctx context
257 * @param[in] result result
258 * @param[in] groupId group id
260 static void handleAclCreateGroupCB(void* ctx, OCStackResult result, void* groupId)
262 OIC_LOG_V(INFO, TAG, "Received gid = %s", (char *)groupId);
263 handleCB(ctx, result, groupId);
268 * This function prints group policy and calls default callback function handleCB()
270 * @param[in] ctx context
271 * @param[in] result result
272 * @param[in] gp group policy
274 static void handleAclPolicyCheckCB(void* ctx, OCStackResult result, void* gp)
276 OIC_LOG_V(INFO, TAG, "Received gp = %s", (char *)gp);
277 handleCB(ctx, result, gp);
282 * This function prints received acl and calls default callback function handleCB()
284 * @param[in] ctx context
285 * @param[in] result result
288 static void handleAclIndividualGetInfoCB(void* ctx, OCStackResult result, void* acl)
290 printACL((OicSecAcl_t* )acl);
291 handleCB(ctx, result, acl);
292 //can't delete acl here because its ACE's were added to gAcl
293 //TODO: changes in aclresources.c required to fix that
297 * This function prints received group id list and calls default callback function handleCB()
299 * @param[in] ctx context
300 * @param[in] result result
301 * @param[in] gidList group id list
303 static void handleAclFindMyGroupCB(void* ctx, OCStackResult result, void* gidList)
305 printStringArray((stringArray_t *)gidList);
306 handleCB(ctx, result, gidList);
307 clearStringArray((stringArray_t *)gidList);
311 * This function prints received acl and calls default callback function handleCB()
313 * @param[in] ctx context
314 * @param[in] result result
317 static void handleGetCrlCB(void* ctx, OCStackResult result, void* crl)
319 printCrl((OicSecCrl_t *)crl);
320 handleCB(ctx, result, crl);
321 DeleteCrl((OicSecCrl_t *)crl);
325 * This function prints received invitation response and calls default callback function handleCB()
327 * @param[in] ctx context
328 * @param[in] result result
329 * @param[in] invite invitation response (it has inviteResponse_t* type)
331 static void handleAclGetInvitationCB(void* ctx, OCStackResult result, void* invite)
333 printInviteResponse((inviteResponse_t *)invite);
334 handleCB(ctx, result, invite);
335 clearInviteResponse((inviteResponse_t *)invite);
339 static OCStackResult saveTrustCert(void)
341 OCStackResult res = OC_STACK_ERROR;
342 OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
344 OCByteString trustCertChainArray = {0, 0};
345 const char *filename = "rootca.crt";
347 if (!readFile(filename, &trustCertChainArray))
349 OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
350 OICFree(trustCertChainArray.bytes);
351 return OC_STACK_ERROR;
353 OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.bytes, trustCertChainArray.len);
355 res = OCSaveTrustCertChain(trustCertChainArray.bytes, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
357 if (OC_STACK_OK != res)
359 OIC_LOG(ERROR, TAG, "OCSaveTrustCertChain API error");
363 OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
365 OICFree(trustCertChainArray.bytes);
370 static OCStackResult configSelfOwnership(void)
372 OCStackResult res = OC_STACK_ERROR;
373 OIC_LOG(INFO, TAG, "Configures SVR DB as self-ownership.");
375 res = OCConfigSelfOwnership();
377 if (OC_STACK_OK != res)
379 OIC_LOG(ERROR, TAG, "OCConfigSelfOwnership API error. Please check SVR DB");
383 OIC_LOG(INFO, TAG, "Success to configures SVR DB as self-ownership");
389 static void configSecureStorageHwEmulation()
391 OIC_LOG(INFO, TAG, "Enable Secure Storage HW Emulation");
393 printf(" Enter Own Certificate File Path[~4095]: ");
394 char cert_filepath[4096] = {0,};
395 for(int ret=0; 1!=ret; )
397 ret = scanf("%255s", cert_filepath);
398 for( ; 0x20<=getchar(); ); // for removing overflow garbages
399 // '0x20<=code' is character region
402 printf(" Enter Private Key File Path[~4095]: ");
403 char key_filepath[4096] = {0,};
404 for(int ret=0; 1!=ret; )
406 ret = scanf("%255s", key_filepath);
407 for( ; 0x20<=getchar(); ); // for removing overflow garbages
408 // '0x20<=code' is character region
411 printf(" Enter Password for Key Password[~31][Press (Enter) to not set]: ");
413 for(int i=0; i < 31; i++)
415 pwd[i] = (char)getchar();
428 if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
430 OIC_LOG(ERROR, TAG, " Fail to set cert/key file path");
434 if (0 != SetHwPkixCallbacks(HWGetKeyContext,
436 HWGetOwnCertificateChain,
439 OIC_LOG(ERROR, TAG, " Fail to regist HW Pkix Callbacks");
442 OIC_LOG(INFO, TAG, " Success to regist HW Pkix Callbacks");
445 static void wrongRequest()
447 printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
450 static void userRequests(void *data)
454 OIC_LOG(ERROR, TAG, "Received NULL data");
458 OCMode mode = *(OCMode*)data;
460 memset(&endPoint, 0, sizeof(endPoint));
461 strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
462 endPoint.port = DEFAULT_PORT;
464 mutex = oc_mutex_new();
465 cond = oc_cond_new();
467 while (false == fExit)
469 OCStackResult res = OC_STACK_ERROR;
470 bool sendDataToServer = true;
471 timeout = DEFAULT_RESPONSE_WAIT_TIME;
473 printf("-----------------------------------------------------------\n");
474 printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port);
475 printf("via auth provider: %s\n", authProvider);
476 printf("srv file: %s\n", fname);
477 printf("CoAP prefix: %s\n", DEFAULT_PREFIX);
478 printf("-----------------------------------------------------------\n");
483 readInteger(&request, "Menu number", "see above");
488 if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)))
490 printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK);
492 readString(token, sizeof(token), "auth token", "check link above");
493 res = CloudSignUp(&endPoint, authProvider, token);
496 res = CloudSignIn(&endPoint);
499 res = CloudSignOut(&endPoint);
502 readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
503 sendDataToServer = false;
508 snprintf(example, sizeof(example), "%d", DEFAULT_PORT);
510 readInteger(&tmp, "port number", example);
512 sendDataToServer = false;
516 res = OCWrapperGetCRL(&endPoint, handleGetCrlCB);
519 res = OCWrapperPostCRL(&endPoint, handleCB);
521 case ACL_GROUP_CREATE:
522 res = OCWrapperAclCreateGroup(&endPoint, handleAclCreateGroupCB);
525 res = OCWrapperAclFindMyGroup(&endPoint, handleAclFindMyGroupCB);
527 case ACL_GROUP_DELETE:
528 res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
531 res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB);
533 case ACL_GROUP_OBSERVE:
534 res = OCWrapperAclObserveGroup(&endPoint, handleCB);
536 case ACL_GROUP_SHARE_DEVICE:
537 res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB);
539 case ACL_GROUP_DELETE_DEVICE:
540 res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB);
542 case ACL_GROUP_GET_INFO:
543 res = OCWrapperAclGroupGetInfo(&endPoint, handleCB);
545 case ACL_GROUP_INVITE_USER:
546 res = OCWrapperAclInviteUser(&endPoint, handleCB);
548 case ACL_GROUP_GET_INVITE:
549 res = OCWrapperAclGetInvitation(&endPoint, handleAclGetInvitationCB);
551 case ACL_GROUP_DELETE_INVITE:
552 res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
554 case ACL_GROUP_CANCEL_INVITE:
555 res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
557 case ACL_POLICY_CHECK_REQUEST:
558 res = OCWrapperAclPolicyCheck(&endPoint, handleAclPolicyCheckCB);
560 case ACL_ID_GET_BY_DEVICE:
561 res = OCWrapperAclIdGetByDevice(&endPoint, handleAclIdCB);
564 res = OCWrapperAclIdCreate(&endPoint, handleAclIdCB);
567 res = OCWrapperAclIdDelete(&endPoint, handleCB);
569 case ACL_INDIVIDUAL_GET_INFO:
570 res = OCWrapperAclIndividualGetInfo(&endPoint, handleAclIndividualGetInfoCB);
572 case ACL_INDIVIDUAL_UPDATE_ACE:
573 res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
575 case ACL_INDIVIDUAL_UPDATE:
576 res = OCWrapperAclIndividualUpdate(&endPoint, handleCB);
578 case ACL_INDIVIDUAL_DELETE:
579 res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
581 case ACL_INDIVIDUAL_DELETE_ACE:
582 res = OCWrapperAclIndividualDeleteAce(&endPoint, handleCB);
585 res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
589 res = InitDiscovery();
593 res = InitRequest(OC_REST_GET);
597 res= InitRequest(OC_REST_PUT);
601 res= InitRequest(OC_REST_POST);
606 readInteger(&tmp, "Select Cipher Suite", "0 - ECDSA, other - RSA");
607 uint16_t cipher = tmp? MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256:
608 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
609 if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP))
611 OIC_LOG(ERROR, TAG, "CASelectCipherSuite returned an error");
613 sendDataToServer = false;
616 case SAVE_TRUST_CERT:
618 sendDataToServer = false;
620 case USE_SECURE_CONN:
623 readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
624 setCoapPrefix(0 == tmp ? false : true);
625 sendDataToServer = false;
628 case CONFIG_SELF_OWNERSHIP:
629 configSelfOwnership();
630 sendDataToServer = false;
632 case SECURE_STORAGE_HW_EMULATION:
633 configSecureStorageHwEmulation();
634 sendDataToServer = false;
637 oc_mutex_free(mutex);
640 sendDataToServer = false;
644 sendDataToServer = false;
648 //if requests were sent then wait response
649 if (sendDataToServer)
651 if (OC_STACK_OK == res)
653 oc_mutex_lock(mutex);
654 oc_cond_wait_for(cond, mutex, timeout);
655 oc_mutex_unlock(mutex);
659 OIC_LOG_V(ERROR, TAG, "Request returned an error %d", res);
665 FILE* server_fopen(const char *path, const char *mode)
668 return fopen(fname, mode);
672 * Check file accessibility
674 * @param[in] name file path
675 * @return true if check was successful
677 static bool checkConfig(const char *name)
679 FILE* file = fopen(name, "rb");
689 static void printUsage(char *name)
691 printf("Wrong arguments count!\n");
692 printf("Usage : %s <database_filename>\n", name);
693 printf("Examples : 1) %s 2) %s cloud.dat\n", name, name);
696 bool parseCommandLineArguments(int argc, char *argv[])
703 if (!checkConfig(fname))
705 OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname);
717 OCStackResult initPersistentStorage()
719 //Initialize Persistent Storage for SVR database
720 static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
722 return OCRegisterPersistentStorageHandler(&ps);
725 OCStackResult startRequestsThread(OCMode *mode)
727 CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle);
728 if (CA_STATUS_OK != res)
730 OIC_LOG(ERROR, TAG, "thread pool initialize error.");
734 res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode, NULL);
735 if (CA_STATUS_OK != res)
737 OIC_LOG(ERROR, TAG, "thread pool add task error.");
738 ca_thread_pool_free(g_threadPoolHandle);
743 OCStackResult initProcess(OCMode mode)
745 return OCInit(NULL, 0, mode);
750 struct timespec timeout;
752 timeout.tv_nsec = 100000000L;
754 while(false == fExit)
756 if (OCProcess() != OC_STACK_OK)
758 OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
761 nanosleep(&timeout, NULL);
764 if (OCStop() != OC_STACK_OK)
766 OIC_LOG(ERROR, TAG, "OCStop process error\n");
770 void freeThreadResources()
772 if (g_threadPoolHandle)
774 ca_thread_pool_free(g_threadPoolHandle);