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_DELETE = 42,
102 ACL_GROUP_CREATE = 50,
105 ACL_GROUP_OBSERVE= 53,
106 ACL_GROUP_DELETE = 54,
108 ACL_GROUP_SHARE_DEVICE = 60,
109 ACL_GROUP_DELETE_DEVICE = 61,
110 ACL_GROUP_GET_INFO = 62,
112 ACL_POLICY_CHECK_REQUEST = 70,
114 ACL_GROUP_INVITE_USER = 80,
115 ACL_GROUP_GET_INVITE = 81,
116 ACL_GROUP_DELETE_INVITE = 82,
117 ACL_GROUP_CANCEL_INVITE = 83,
122 static void printMenu(OCMode mode)
124 char *title = "Client";
125 if (OC_SERVER == mode)
129 printf("************************************************************\n");
130 printf("****************** Cloud %s Requests *******************\n", title);
131 printf("************************************************************\n");
132 printf("** AUTHORIZATION\n");
133 printf("** %d - Sign Up request\n", SIGN_UP);
134 printf("** %d - Sign In request\n", SIGN_IN);
135 printf("** %d - Sign Out request\n", SIGN_OUT);
137 printf("** SETTINGS \n");
138 printf("** %d - Change default host\n", HOST);
139 printf("** %d - Change default port\n", PORT);
140 printf("** %d - Change default database filename\n", DB_FILE);
141 printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
142 printf("** %d - Change TLS cipher suite (ECDSA/RSA)\n", USE_RSA);
143 printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
144 printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
146 if (OC_CLIENT == mode)
148 printf("** DISCOVERY\n");
149 printf("** %d - Start Discovery\n", DISCOVERY);
150 printf("** %d - Get Request\n", GET);
151 printf("** %d - Put Request\n", PUT);
152 printf("** %d - Post Request\n", POST);
155 printf("** CERTIFICATE REQUEST\n");
156 printf("** %d - Certificate Request\n", CSR_SIGN);
159 printf("** %d - CRL GET Request\n", CRL_GET);
160 printf("** %d - CRL POST Request\n", CRL_POST);
162 printf("** ACL MANAGER\n");
163 printf("** %d - ACL id create Request\n", ACL_ID_CREATE);
164 printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE);
165 printf("** %d - ACL id delete Request\n", ACL_ID_DELETE);
167 printf("** ACL INDIVIDUAL\n");
168 printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
169 printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
170 printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
172 printf("** ACL GROUP MANAGER\n");
173 printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
174 printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND);
175 printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN);
176 printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE);
177 printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE);
179 printf("** ACL INDIVIDUAL GROUP\n");
180 printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE);
181 printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE);
182 printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO);
184 printf("** ACL POLICY ENFORCEMENT\n");
185 printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST);
187 printf("** ACL MEMBER INVITATION\n");
188 printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER);
189 printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE);
190 printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE);
191 printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
194 printf("** %d - Exit cloud %s\n", EXIT, title);
195 printf("************************************************************\n");
198 void unlockMenu(void *data)
204 ca_mutex_lock(mutex);
205 ca_cond_signal(cond);
206 ca_mutex_unlock(mutex);
211 * This is default callback to all requests
212 * Used to sync with main menu
214 * @param[in] ctx context
215 * @param[in] result result
216 * @param[in] data data
218 static void handleCB(void* ctx, OCStackResult result, void* data)
223 OIC_LOG_V(INFO, TAG, "%s: Received result = %d", __func__, result);
229 * This function prints Acl id and calls default callback function handleCB()
231 * @param[in] ctx context
232 * @param[in] result result
233 * @param[in] aclId acl id
235 static void handleAclIdCB(void* ctx, OCStackResult result, void* aclId)
237 OIC_LOG_V(INFO, TAG, "Received Acl id = %s", (char *)aclId);
238 handleCB(ctx, result, aclId);
243 * This function prints group id and calls default callback function handleCB()
245 * @param[in] ctx context
246 * @param[in] result result
247 * @param[in] groupId group id
249 static void handleAclCreateGroupCB(void* ctx, OCStackResult result, void* groupId)
251 OIC_LOG_V(INFO, TAG, "Received gid = %s", (char *)groupId);
252 handleCB(ctx, result, groupId);
257 * This function prints group policy and calls default callback function handleCB()
259 * @param[in] ctx context
260 * @param[in] result result
261 * @param[in] gp group policy
263 static void handleAclPolicyCheckCB(void* ctx, OCStackResult result, void* gp)
265 OIC_LOG_V(INFO, TAG, "Received gp = %s", (char *)gp);
266 handleCB(ctx, result, gp);
271 * This function prints received acl and calls default callback function handleCB()
273 * @param[in] ctx context
274 * @param[in] result result
277 static void handleAclIndividualGetInfoCB(void* ctx, OCStackResult result, void* acl)
279 printACL((OicSecAcl_t* )acl);
280 handleCB(ctx, result, acl);
281 //can't delete acl here because its ACE's were added to gAcl
282 //TODO: changes in aclresources.c required to fix that
286 * This function prints received group id list and calls default callback function handleCB()
288 * @param[in] ctx context
289 * @param[in] result result
290 * @param[in] gidList group id list
292 static void handleAclFindMyGroupCB(void* ctx, OCStackResult result, void* gidList)
294 printStringArray((stringArray_t *)gidList);
295 handleCB(ctx, result, gidList);
296 clearStringArray((stringArray_t *)gidList);
300 * This function prints received acl and calls default callback function handleCB()
302 * @param[in] ctx context
303 * @param[in] result result
306 static void handleGetCrlCB(void* ctx, OCStackResult result, void* crl)
308 printCrl((OicSecCrl_t *)crl);
309 handleCB(ctx, result, crl);
310 DeleteCrl((OicSecCrl_t *)crl);
314 * This function prints received invitation response and calls default callback function handleCB()
316 * @param[in] ctx context
317 * @param[in] result result
318 * @param[in] invite invitation response (it has inviteResponse_t* type)
320 static void handleAclGetInvitationCB(void* ctx, OCStackResult result, void* invite)
322 printInviteResponse((inviteResponse_t *)invite);
323 handleCB(ctx, result, invite);
324 clearInviteResponse((inviteResponse_t *)invite);
328 static OCStackResult saveTrustCert(void)
330 OCStackResult res = OC_STACK_ERROR;
331 OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
333 ByteArray_t trustCertChainArray = {0, 0};
334 const char *filename = "rootca.crt";
336 if (!readFile(filename, (OCByteString *)&trustCertChainArray))
338 OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
339 return OC_STACK_ERROR;
341 OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
343 res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
345 if (OC_STACK_OK != res)
347 OIC_LOG(ERROR, TAG, "OCSaveTrustCertChain API error");
351 OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
353 OICFree(trustCertChainArray.data);
358 static void wrongRequest()
360 printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
363 static void userRequests(void *data)
367 OIC_LOG(ERROR, TAG, "Received NULL data");
371 OCMode mode = *(OCMode*)data;
373 memset(&endPoint, 0, sizeof(endPoint));
374 strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
375 endPoint.port = DEFAULT_PORT;
377 mutex = ca_mutex_new();
378 cond = ca_cond_new();
380 while (false == fExit)
382 OCStackResult res = OC_STACK_ERROR;
383 bool sendDataToServer = true;
384 timeout = DEFAULT_RESPONSE_WAIT_TIME;
386 printf("-----------------------------------------------------------\n");
387 printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port);
388 printf("via auth provider: %s\n", authProvider);
389 printf("srv file: %s\n", fname);
390 printf("CoAP prefix: %s\n", DEFAULT_PREFIX);
391 printf("-----------------------------------------------------------\n");
396 readInteger(&request, "Menu number", "see above");
401 if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)))
403 printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK);
405 readString(token, sizeof(token), "auth token", "check link above");
406 res = CloudSignUp(&endPoint, authProvider, token);
409 res = CloudSignIn(&endPoint);
412 res = CloudSignOut(&endPoint);
415 readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
416 sendDataToServer = false;
421 snprintf(example, sizeof(example), "%d", DEFAULT_PORT);
423 readInteger(&tmp, "port number", example);
425 sendDataToServer = false;
429 res = OCWrapperGetCRL(&endPoint, handleGetCrlCB);
432 res = OCWrapperPostCRL(&endPoint, handleCB);
434 case ACL_GROUP_CREATE:
435 res = OCWrapperAclCreateGroup(&endPoint, handleAclCreateGroupCB);
438 res = OCWrapperAclFindMyGroup(&endPoint, handleAclFindMyGroupCB);
440 case ACL_GROUP_DELETE:
441 res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
444 res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB);
446 case ACL_GROUP_OBSERVE:
447 res = OCWrapperAclObserveGroup(&endPoint, handleCB);
449 case ACL_GROUP_SHARE_DEVICE:
450 res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB);
452 case ACL_GROUP_DELETE_DEVICE:
453 res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB);
455 case ACL_GROUP_GET_INFO:
456 res = OCWrapperAclGroupGetInfo(&endPoint, handleCB);
458 case ACL_GROUP_INVITE_USER:
459 res = OCWrapperAclInviteUser(&endPoint, handleCB);
461 case ACL_GROUP_GET_INVITE:
462 res = OCWrapperAclGetInvitation(&endPoint, handleAclGetInvitationCB);
464 case ACL_GROUP_DELETE_INVITE:
465 res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
467 case ACL_GROUP_CANCEL_INVITE:
468 res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
470 case ACL_POLICY_CHECK_REQUEST:
471 res = OCWrapperAclPolicyCheck(&endPoint, handleAclPolicyCheckCB);
473 case ACL_ID_GET_BY_DEVICE:
474 res = OCWrapperAclIdGetByDevice(&endPoint, handleAclIdCB);
477 res = OCWrapperAclIdCreate(&endPoint, handleAclIdCB);
480 res = OCWrapperAclIdDelete(&endPoint, handleCB);
482 case ACL_INDIVIDUAL_GET_INFO:
483 res = OCWrapperAclIndividualGetInfo(&endPoint, handleAclIndividualGetInfoCB);
485 case ACL_INDIVIDUAL_UPDATE_ACE:
486 res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
488 case ACL_INDIVIDUAL_DELETE:
489 res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
492 res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
496 res = InitDiscovery();
500 res = InitRequest(OC_REST_GET);
504 res= InitRequest(OC_REST_PUT);
508 res= InitRequest(OC_REST_POST);
513 readInteger(&tmp, "Select Cipher Suite", "0 - ECDSA, other - RSA");
514 uint16_t cipher = tmp? MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA:
515 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
516 if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP))
518 OIC_LOG(ERROR, TAG, "CASelectCipherSuite returned an error");
520 sendDataToServer = false;
523 case SAVE_TRUST_CERT:
525 sendDataToServer = false;
527 case USE_SECURE_CONN:
530 readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
531 setCoapPrefix(0 == tmp ? false : true);
532 sendDataToServer = false;
536 ca_mutex_free(mutex);
539 sendDataToServer = false;
543 sendDataToServer = false;
547 //if requests were sent then wait response
548 if (sendDataToServer)
550 if (OC_STACK_OK == res)
552 ca_mutex_lock(mutex);
553 ca_cond_wait_for(cond, mutex, timeout);
554 ca_mutex_unlock(mutex);
558 OIC_LOG_V(ERROR, TAG, "Request returned an error %d", res);
564 FILE* server_fopen(const char *path, const char *mode)
567 return fopen(fname, mode);
571 * Check file accessibility
573 * @param[in] name file path
574 * @return true if check was successful
576 static bool checkConfig(const char *name)
578 FILE* file = fopen(name, "rb");
588 static void printUsage(char *name)
590 printf("Wrong arguments count!\n");
591 printf("Usage : %s <database_filename>\n", name);
592 printf("Examples : 1) %s 2) %s cloud.dat\n", name, name);
595 bool parseCommandLineArguments(int argc, char *argv[])
602 if (!checkConfig(fname))
604 OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname);
616 OCStackResult initPersistentStorage()
618 //Initialize Persistent Storage for SVR database
619 static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
621 return OCRegisterPersistentStorageHandler(&ps);
624 OCStackResult startRequestsThread(OCMode *mode)
626 CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle);
627 if (CA_STATUS_OK != res)
629 OIC_LOG(ERROR, TAG, "thread pool initialize error.");
633 res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode);
634 if (CA_STATUS_OK != res)
636 OIC_LOG(ERROR, TAG, "thread pool add task error.");
637 ca_thread_pool_free(g_threadPoolHandle);
642 OCStackResult initProcess(OCMode mode)
644 return OCInit(NULL, 0, mode);
649 while(false == fExit)
651 if (OCProcess() != OC_STACK_OK)
653 OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
658 if (OCStop() != OC_STACK_OK)
660 OIC_LOG(ERROR, TAG, "OCStop process error\n");
664 void freeThreadResources()
666 if (g_threadPoolHandle)
668 ca_thread_pool_free(g_threadPoolHandle);