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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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 #include "casecurityinterface.h"
34 #include "mbedtls/ssl_ciphersuites.h"
37 #include "cloudAuth.h"
38 #include "cloudCommon.h"
39 #include "cloudWrapper.h"
40 #include "cloudDiscovery.h"
43 #include <unistd.h> //for unlink
46 #define TAG "cloudCommon"
48 #define DEFAULT_HOST "10.113.68.85"//"127.0.0.1"
49 #define DEFAULT_PORT OC_MULTICAST_PORT
50 #define DEFAULT_AUTH_PROVIDER "github"
51 #define DEFAULT_DB_FILE "./cloud.dat"
52 #define DEFAULT_RESPONSE_WAIT_TIME (10 * 1000000) //10s
54 #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"
56 #define CLIENT_ONLY(mode) if (OC_SERVER == (mode)) { wrongRequest(); sendDataToServer = false; break; }
58 static bool fExit = false;
60 static ca_thread_pool_t g_threadPoolHandle = NULL;
61 static OCDevAddr endPoint;
62 static char token[1024] = "";
63 static char authProvider[1024] = DEFAULT_AUTH_PROVIDER;
64 static char *fname = DEFAULT_DB_FILE;
65 static uint64_t timeout;
66 static uint16_t g_credId = 0;
69 static ca_mutex mutex;
95 ACL_ID_GET_BY_DEVICE = 31,
98 ACL_INDIVIDUAL_GET_INFO = 40,
99 ACL_INDIVIDUAL_UPDATE_ACE = 41,
100 ACL_INDIVIDUAL_UPDATE = 42,
101 ACL_INDIVIDUAL_DELETE = 43,
102 ACL_INDIVIDUAL_DELETE_ACE = 44,
104 ACL_GROUP_CREATE = 50,
107 ACL_GROUP_OBSERVE= 53,
108 ACL_GROUP_DELETE = 54,
110 ACL_GROUP_SHARE_DEVICE = 60,
111 ACL_GROUP_DELETE_DEVICE = 61,
112 ACL_GROUP_GET_INFO = 62,
114 ACL_POLICY_CHECK_REQUEST = 70,
116 ACL_GROUP_INVITE_USER = 80,
117 ACL_GROUP_GET_INVITE = 81,
118 ACL_GROUP_DELETE_INVITE = 82,
119 ACL_GROUP_CANCEL_INVITE = 83,
124 static void printMenu(OCMode mode)
126 char *title = "Client";
127 if (OC_SERVER == mode)
131 printf("************************************************************\n");
132 printf("****************** Cloud %s Requests *******************\n", title);
133 printf("************************************************************\n");
134 printf("** AUTHORIZATION\n");
135 printf("** %d - Sign Up request\n", SIGN_UP);
136 printf("** %d - Sign In request\n", SIGN_IN);
137 printf("** %d - Sign Out request\n", SIGN_OUT);
139 printf("** SETTINGS \n");
140 printf("** %d - Change default host\n", HOST);
141 printf("** %d - Change default port\n", PORT);
142 printf("** %d - Change default database filename\n", DB_FILE);
143 printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
144 printf("** %d - Change TLS cipher suite (ECDSA/RSA)\n", USE_RSA);
145 printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
146 printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
148 if (OC_CLIENT == mode)
150 printf("** DISCOVERY\n");
151 printf("** %d - Start Discovery\n", DISCOVERY);
152 printf("** %d - Get Request\n", GET);
153 printf("** %d - Put Request\n", PUT);
154 printf("** %d - Post Request\n", POST);
157 printf("** CERTIFICATE REQUEST\n");
158 printf("** %d - Certificate Request\n", CSR_SIGN);
161 printf("** %d - CRL GET Request\n", CRL_GET);
162 printf("** %d - CRL POST Request\n", CRL_POST);
164 printf("** ACL MANAGER\n");
165 printf("** %d - ACL id create Request\n", ACL_ID_CREATE);
166 printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE);
167 printf("** %d - ACL id delete Request\n", ACL_ID_DELETE);
169 printf("** ACL INDIVIDUAL\n");
170 printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
171 printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
172 printf("** %d - ACL individual update Request\n", ACL_INDIVIDUAL_UPDATE);
173 printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
174 printf("** %d - ACL individual delete ACE Request\n", ACL_INDIVIDUAL_DELETE_ACE);
176 printf("** ACL GROUP MANAGER\n");
177 printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
178 printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND);
179 printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN);
180 printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE);
181 printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE);
183 printf("** ACL INDIVIDUAL GROUP\n");
184 printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE);
185 printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE);
186 printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO);
188 printf("** ACL POLICY ENFORCEMENT\n");
189 printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST);
191 printf("** ACL MEMBER INVITATION\n");
192 printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER);
193 printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE);
194 printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE);
195 printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
198 printf("** %d - Exit cloud %s\n", EXIT, title);
199 printf("************************************************************\n");
202 void unlockMenu(void *data)
208 ca_mutex_lock(mutex);
209 ca_cond_signal(cond);
210 ca_mutex_unlock(mutex);
215 * This is default callback to all requests
216 * Used to sync with main menu
218 * @param[in] ctx context
219 * @param[in] result result
220 * @param[in] data data
222 static void handleCB(void* ctx, OCStackResult result, void* data)
227 OIC_LOG_V(INFO, TAG, "%s: Received result = %d", __func__, result);
233 * This function prints Acl id and calls default callback function handleCB()
235 * @param[in] ctx context
236 * @param[in] result result
237 * @param[in] aclId acl id
239 static void handleAclIdCB(void* ctx, OCStackResult result, void* aclId)
241 OIC_LOG_V(INFO, TAG, "Received Acl id = %s", (char *)aclId);
242 handleCB(ctx, result, aclId);
247 * This function prints group id and calls default callback function handleCB()
249 * @param[in] ctx context
250 * @param[in] result result
251 * @param[in] groupId group id
253 static void handleAclCreateGroupCB(void* ctx, OCStackResult result, void* groupId)
255 OIC_LOG_V(INFO, TAG, "Received gid = %s", (char *)groupId);
256 handleCB(ctx, result, groupId);
261 * This function prints group policy and calls default callback function handleCB()
263 * @param[in] ctx context
264 * @param[in] result result
265 * @param[in] gp group policy
267 static void handleAclPolicyCheckCB(void* ctx, OCStackResult result, void* gp)
269 OIC_LOG_V(INFO, TAG, "Received gp = %s", (char *)gp);
270 handleCB(ctx, result, gp);
275 * This function prints received acl and calls default callback function handleCB()
277 * @param[in] ctx context
278 * @param[in] result result
281 static void handleAclIndividualGetInfoCB(void* ctx, OCStackResult result, void* acl)
283 printACL((OicSecAcl_t* )acl);
284 handleCB(ctx, result, acl);
285 //can't delete acl here because its ACE's were added to gAcl
286 //TODO: changes in aclresources.c required to fix that
290 * This function prints received group id list and calls default callback function handleCB()
292 * @param[in] ctx context
293 * @param[in] result result
294 * @param[in] gidList group id list
296 static void handleAclFindMyGroupCB(void* ctx, OCStackResult result, void* gidList)
298 printStringArray((stringArray_t *)gidList);
299 handleCB(ctx, result, gidList);
300 clearStringArray((stringArray_t *)gidList);
304 * This function prints received acl and calls default callback function handleCB()
306 * @param[in] ctx context
307 * @param[in] result result
310 static void handleGetCrlCB(void* ctx, OCStackResult result, void* crl)
312 printCrl((OicSecCrl_t *)crl);
313 handleCB(ctx, result, crl);
314 DeleteCrl((OicSecCrl_t *)crl);
318 * This function prints received invitation response and calls default callback function handleCB()
320 * @param[in] ctx context
321 * @param[in] result result
322 * @param[in] invite invitation response (it has inviteResponse_t* type)
324 static void handleAclGetInvitationCB(void* ctx, OCStackResult result, void* invite)
326 printInviteResponse((inviteResponse_t *)invite);
327 handleCB(ctx, result, invite);
328 clearInviteResponse((inviteResponse_t *)invite);
332 static OCStackResult saveTrustCert(void)
334 OCStackResult res = OC_STACK_ERROR;
335 OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
337 ByteArray_t trustCertChainArray = {0, 0};
338 const char *filename = "rootca.crt";
340 if (!readFile(filename, (OCByteString *)&trustCertChainArray))
342 OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
343 OICFree(((OCByteString *)&trustCertChainArray)->bytes);
344 return OC_STACK_ERROR;
346 OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
348 res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
350 if (OC_STACK_OK != res)
352 OIC_LOG(ERROR, TAG, "OCSaveTrustCertChain API error");
356 OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
358 OICFree(trustCertChainArray.data);
363 static void wrongRequest()
365 printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
368 static void userRequests(void *data)
372 OIC_LOG(ERROR, TAG, "Received NULL data");
376 OCMode mode = *(OCMode*)data;
378 memset(&endPoint, 0, sizeof(endPoint));
379 strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
380 endPoint.port = DEFAULT_PORT;
382 mutex = ca_mutex_new();
383 cond = ca_cond_new();
385 while (false == fExit)
387 OCStackResult res = OC_STACK_ERROR;
388 bool sendDataToServer = true;
389 timeout = DEFAULT_RESPONSE_WAIT_TIME;
391 printf("-----------------------------------------------------------\n");
392 printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port);
393 printf("via auth provider: %s\n", authProvider);
394 printf("srv file: %s\n", fname);
395 printf("CoAP prefix: %s\n", DEFAULT_PREFIX);
396 printf("-----------------------------------------------------------\n");
401 readInteger(&request, "Menu number", "see above");
406 if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)))
408 printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK);
410 readString(token, sizeof(token), "auth token", "check link above");
411 res = CloudSignUp(&endPoint, authProvider, token);
414 res = CloudSignIn(&endPoint);
417 res = CloudSignOut(&endPoint);
420 readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
421 sendDataToServer = false;
426 snprintf(example, sizeof(example), "%d", DEFAULT_PORT);
428 readInteger(&tmp, "port number", example);
430 sendDataToServer = false;
434 res = OCWrapperGetCRL(&endPoint, handleGetCrlCB);
437 res = OCWrapperPostCRL(&endPoint, handleCB);
439 case ACL_GROUP_CREATE:
440 res = OCWrapperAclCreateGroup(&endPoint, handleAclCreateGroupCB);
443 res = OCWrapperAclFindMyGroup(&endPoint, handleAclFindMyGroupCB);
445 case ACL_GROUP_DELETE:
446 res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
449 res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB);
451 case ACL_GROUP_OBSERVE:
452 res = OCWrapperAclObserveGroup(&endPoint, handleCB);
454 case ACL_GROUP_SHARE_DEVICE:
455 res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB);
457 case ACL_GROUP_DELETE_DEVICE:
458 res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB);
460 case ACL_GROUP_GET_INFO:
461 res = OCWrapperAclGroupGetInfo(&endPoint, handleCB);
463 case ACL_GROUP_INVITE_USER:
464 res = OCWrapperAclInviteUser(&endPoint, handleCB);
466 case ACL_GROUP_GET_INVITE:
467 res = OCWrapperAclGetInvitation(&endPoint, handleAclGetInvitationCB);
469 case ACL_GROUP_DELETE_INVITE:
470 res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
472 case ACL_GROUP_CANCEL_INVITE:
473 res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
475 case ACL_POLICY_CHECK_REQUEST:
476 res = OCWrapperAclPolicyCheck(&endPoint, handleAclPolicyCheckCB);
478 case ACL_ID_GET_BY_DEVICE:
479 res = OCWrapperAclIdGetByDevice(&endPoint, handleAclIdCB);
482 res = OCWrapperAclIdCreate(&endPoint, handleAclIdCB);
485 res = OCWrapperAclIdDelete(&endPoint, handleCB);
487 case ACL_INDIVIDUAL_GET_INFO:
488 res = OCWrapperAclIndividualGetInfo(&endPoint, handleAclIndividualGetInfoCB);
490 case ACL_INDIVIDUAL_UPDATE_ACE:
491 res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
493 case ACL_INDIVIDUAL_UPDATE:
494 res = OCWrapperAclIndividualUpdate(&endPoint, handleCB);
496 case ACL_INDIVIDUAL_DELETE:
497 res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
499 case ACL_INDIVIDUAL_DELETE_ACE:
500 res = OCWrapperAclIndividualDeleteAce(&endPoint, handleCB);
503 res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
507 res = InitDiscovery();
511 res = InitRequest(OC_REST_GET);
515 res= InitRequest(OC_REST_PUT);
519 res= InitRequest(OC_REST_POST);
524 readInteger(&tmp, "Select Cipher Suite", "0 - ECDSA, other - RSA");
525 uint16_t cipher = tmp? MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA:
526 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
527 if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP))
529 OIC_LOG(ERROR, TAG, "CASelectCipherSuite returned an error");
531 sendDataToServer = false;
534 case SAVE_TRUST_CERT:
536 sendDataToServer = false;
538 case USE_SECURE_CONN:
541 readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
542 setCoapPrefix(0 == tmp ? false : true);
543 sendDataToServer = false;
547 ca_mutex_free(mutex);
550 sendDataToServer = false;
554 sendDataToServer = false;
558 //if requests were sent then wait response
559 if (sendDataToServer)
561 if (OC_STACK_OK == res)
563 ca_mutex_lock(mutex);
564 ca_cond_wait_for(cond, mutex, timeout);
565 ca_mutex_unlock(mutex);
569 OIC_LOG_V(ERROR, TAG, "Request returned an error %d", res);
575 FILE* server_fopen(const char *path, const char *mode)
578 return fopen(fname, mode);
582 * Check file accessibility
584 * @param[in] name file path
585 * @return true if check was successful
587 static bool checkConfig(const char *name)
589 FILE* file = fopen(name, "rb");
599 static void printUsage(char *name)
601 printf("Wrong arguments count!\n");
602 printf("Usage : %s <database_filename>\n", name);
603 printf("Examples : 1) %s 2) %s cloud.dat\n", name, name);
606 bool parseCommandLineArguments(int argc, char *argv[])
613 if (!checkConfig(fname))
615 OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname);
627 OCStackResult initPersistentStorage()
629 //Initialize Persistent Storage for SVR database
630 static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
632 return OCRegisterPersistentStorageHandler(&ps);
635 OCStackResult startRequestsThread(OCMode *mode)
637 CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle);
638 if (CA_STATUS_OK != res)
640 OIC_LOG(ERROR, TAG, "thread pool initialize error.");
644 res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode);
645 if (CA_STATUS_OK != res)
647 OIC_LOG(ERROR, TAG, "thread pool add task error.");
648 ca_thread_pool_free(g_threadPoolHandle);
653 OCStackResult initProcess(OCMode mode)
655 return OCInit(NULL, 0, mode);
660 while(false == fExit)
662 if (OCProcess() != OC_STACK_OK)
664 OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
669 if (OCStop() != OC_STACK_OK)
671 OIC_LOG(ERROR, TAG, "OCStop process error\n");
675 void freeThreadResources()
677 if (g_threadPoolHandle)
679 ca_thread_pool_free(g_threadPoolHandle);