From 1097d2acfbf5098a04c3d007f11a0717951f07b1 Mon Sep 17 00:00:00 2001 From: Ashwini Kumar Date: Fri, 2 Sep 2016 12:39:57 +0530 Subject: [PATCH] Add C++ Cloud provisioning [#1]: Initial version of header [#2]: APIs definition Added Unit Tests. Added cloudClient, based on the C cloudClient. Only the focus APIs are changed to C++ Change-Id: I482f19b80e674ebccae44731a9927ab19c2b4a80 Signed-off-by: Ashwini Kumar Reviewed-on: https://gerrit.iotivity.org/gerrit/11331 Tested-by: jenkins-iotivity Reviewed-by: Randeep Singh --- .../security/provisioning/include/cloud/utils.h | 7 +- .../csdk/security/provisioning/src/cloud/csr.c | 1 + resource/include/OCCloudProvisioning.h | 139 +++++ resource/include/OCProvisioningManager.h | 3 + resource/provisioning/SConscript | 9 +- resource/provisioning/examples/SConscript | 15 + resource/provisioning/examples/cloud.dat | Bin 0 -> 878 bytes resource/provisioning/examples/cloudAuth.cpp | 462 ++++++++++++++++ resource/provisioning/examples/cloudAuth.h | 90 +++ resource/provisioning/examples/cloudClient.cpp | 524 ++++++++++++++++++ resource/provisioning/examples/cloudWrapper.cpp | 615 +++++++++++++++++++++ resource/provisioning/examples/cloudWrapper.h | 245 ++++++++ .../provisioning/examples/provisioningclient.cpp | 2 +- resource/provisioning/examples/rootca.crt | 19 + resource/provisioning/src/OCCloudProvisioning.cpp | 211 +++++++ .../unittests/OCCloudProvisioningTest.cpp | 81 +++ resource/provisioning/unittests/SConscript | 12 +- service/easy-setup/mediator/richsdk/SConscript | 3 +- .../mediator/linux/richsdk_sample/SConscript | 1 + 19 files changed, 2434 insertions(+), 5 deletions(-) create mode 100755 resource/include/OCCloudProvisioning.h create mode 100644 resource/provisioning/examples/cloud.dat create mode 100644 resource/provisioning/examples/cloudAuth.cpp create mode 100644 resource/provisioning/examples/cloudAuth.h create mode 100644 resource/provisioning/examples/cloudClient.cpp create mode 100644 resource/provisioning/examples/cloudWrapper.cpp create mode 100644 resource/provisioning/examples/cloudWrapper.h create mode 100644 resource/provisioning/examples/rootca.crt create mode 100644 resource/provisioning/src/OCCloudProvisioning.cpp create mode 100755 resource/provisioning/unittests/OCCloudProvisioningTest.cpp diff --git a/resource/csdk/security/provisioning/include/cloud/utils.h b/resource/csdk/security/provisioning/include/cloud/utils.h index f6b1c04..eb521b0 100644 --- a/resource/csdk/security/provisioning/include/cloud/utils.h +++ b/resource/csdk/security/provisioning/include/cloud/utils.h @@ -21,6 +21,9 @@ #define CLOUD_UTILS_H #include "occloudprovisioning.h" +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus extern char *DEFAULT_QUERY; extern char *DEFAULT_PREFIX; @@ -60,5 +63,7 @@ char *getDeviceId(); * @param[out] list array of strings structure to clear */ void clearStringArray(stringArray_t *list); - +#ifdef __cplusplus +} +#endif // __cplusplus #endif // CLOUD_UTILS_H diff --git a/resource/csdk/security/provisioning/src/cloud/csr.c b/resource/csdk/security/provisioning/src/cloud/csr.c index f95328d..1a7cb2a 100644 --- a/resource/csdk/security/provisioning/src/cloud/csr.c +++ b/resource/csdk/security/provisioning/src/cloud/csr.c @@ -475,6 +475,7 @@ OCStackResult OCCloudCertificateIssueRequest(void* ctx, snprintf(uri, MAX_URI_QUERY, DEFAULT_QUERY, endPoint->addr, endPoint->port, OC_RSRVD_PROV_CERT_URI); + OIC_LOG_V(DEBUG, TAG, "Certificate Request Query: %s", uri); OCCallbackData cbData; fillCallbackData(&cbData, ctx, callback, HandleCertificateIssueRequest, NULL); diff --git a/resource/include/OCCloudProvisioning.h b/resource/include/OCCloudProvisioning.h new file mode 100755 index 0000000..dbb9998 --- /dev/null +++ b/resource/include/OCCloudProvisioning.h @@ -0,0 +1,139 @@ +//**************************************************************** +// +// Copyright 2016 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_CLOUD_PROVISIONING_CXX_H_ +#define OC_CLOUD_PROVISIONING_CXX_H_ + +#include + +#include "occloudprovisioning.h" +#include "OCApi.h" +#include "OCPlatform_impl.h" + +namespace OC +{ + typedef std::function ResponseCallBack; + typedef std::function AclIdResponseCallBack; + + /** + * Context to be passed to the underlying stack. This is passed back as argument + * to the callback function + */ + struct CloudProvisionContext + { + ResponseCallBack callback; + CloudProvisionContext(ResponseCallBack cb) : callback(cb){} + }; + + struct AclIdContext + { + AclIdResponseCallBack callback; + AclIdContext(AclIdResponseCallBack cb) : callback(cb){} + }; + + class OCCloudProvisioning + { + + private: + OCDevAddr m_devAddr; + std::weak_ptr m_csdkLock; + public: + + /** + * API to construct the CloudProvisioning + * @param ipAddr address of the cloud server + * @param port port of the cloud server + */ + OCCloudProvisioning(std::string& ipAddr, uint16_t port); + ~OCCloudProvisioning(); + + void setIpAddr(std::string& ipAddr) + { + memcpy(m_devAddr.addr, ipAddr.c_str(), MAX_ADDR_STR_SIZE); + } + + void setPort(uint16_t port) + { + m_devAddr.port = port; + } + + /** + * API to Request a certificate from the cloud + * @param callback function called by the stack on completion of request + * @return ::OC_STACK_OK on Success and other values otherwise + */ + OCStackResult requestCertificate(ResponseCallBack callback); + + /** + * API to get ACL ID for the device + * @param deviceId device ID for which the Acl ID is requested + * @param callback function called by the stack on completion of request + * @return ::OC_STACK_OK on Success and other values otherwise + */ + OCStackResult getAclIdByDevice(const std::string& deviceId, AclIdResponseCallBack callback); + + /** + * API to get ACL information about the given Acl ID + * @param aclId ACL ID for which the Acl information is requested + * @param callback function called by the stack on completion of request + * @return ::OC_STACK_OK on Success and other values otherwise + */ + OCStackResult getIndividualAclInfo(const std::string& aclId, ResponseCallBack callback); + + /** + * API to get certificate revocation list + * @param callback function called by the stack on completion of request + * @return ::OC_STACK_OK on Success and other values otherwise + */ + OCStackResult getCRL(ResponseCallBack callback); + + /** + * API to post the certificate revocation list to cloud + * @param thisUpdate thisUpdate [mandatory param] + * @param nextUpdate nextUpdate [mandatory param] + * @param crl revocation list [optional] + * @param serialNumbers [optional] + * @param callback function called by the stack on completion of request + * @return ::OC_STACK_OK on Success and other values otherwise + */ + OCStackResult postCRL(const std::string& thisUpdate, + const std::string& nextUpdate, + const OCByteString *crl, + const stringArray_t *serialNumbers, + ResponseCallBack callback); + + /** + * Common callback wrapper for all the callback functions. + * @param ctx user context passed to the request API + * @param result result of the request performed + * @param data response data + */ + static void callbackWrapper(void* ctx, OCStackResult result, void* data); + + /** + * Callback wrapper for Acl ID get request + * @param ctx user context passed to the request API + * @param result result of the request performed + * @param data AclID for the device + */ + static void aclIdResponseWrapper(void* ctx, OCStackResult result, void* data); + }; +} +#endif //OC_CLOUD_PROVISIONING_CXX_H_ diff --git a/resource/include/OCProvisioningManager.h b/resource/include/OCProvisioningManager.h index b917b3d..f42d662 100644 --- a/resource/include/OCProvisioningManager.h +++ b/resource/include/OCProvisioningManager.h @@ -27,6 +27,9 @@ #include "ocprovisioningmanager.h" #include "OCApi.h" #include "OCPlatform_impl.h" +#ifdef __WITH_TLS__ +#include "OCCloudProvisioning.h" +#endif namespace OC { diff --git a/resource/provisioning/SConscript b/resource/provisioning/SConscript index 9b2d7a3..bbcb933 100644 --- a/resource/provisioning/SConscript +++ b/resource/provisioning/SConscript @@ -44,7 +44,9 @@ ocprovision_env.AppendUnique(CPPPATH = [ '../csdk/security/provisioning/include', '../csdk/security/provisioning/include/oxm', '../csdk/security/provisioning/include/internal', - '../../extlibs/cjson/' + '../csdk/security/provisioning/include/cloud', + '../csdk/connectivity/lib/libcoap-4.1.1/', + '../../extlibs/cjson/' ]) target_os = ocprovision_env.get('TARGET_OS') @@ -71,6 +73,11 @@ ocprovision_src = [ 'src/OCProvisioningManager.cpp' ] +if ocprovision_env.get('WITH_TCP') == True: + ocprovision_src = ocprovision_src + [ + 'src/OCCloudProvisioning.cpp' + ] + ocprovision = ocprovision_env.SharedLibrary('ocprovision', ocprovision_src) ocprovision_env.InstallTarget(ocprovision, 'libocprovision') ocprovision_env.UserInstallTargetLib(ocprovision, 'libocprovision') diff --git a/resource/provisioning/examples/SConscript b/resource/provisioning/examples/SConscript index f873a93..081a0a6 100644 --- a/resource/provisioning/examples/SConscript +++ b/resource/provisioning/examples/SConscript @@ -38,15 +38,19 @@ examples_env = lib_env.Clone() ###################################################################### examples_env.AppendUnique(CPPPATH = [ '../../include/', + '../../../extlibs/cjson', '../../csdk/stack/include', '../../csdk/logger/include', '../../oc_logger/include', '../../csdk/connectivity/api', '../../csdk/connectivity/inc/pkix', + '../../csdk/connectivity/common/inc', + '../../csdk/connectivity/lib/libcoap-4.1.1', '../../csdk/security/include', '../../csdk/security/include/internal', '../../csdk/security/provisioning/include', '../../csdk/security/provisioning/include/oxm', + '../../csdk/security/provisioning/include/cloud', '../../csdk/security/provisioning/include/internal' ]) @@ -93,6 +97,9 @@ if target_os == 'tizen': ###################################################################### provisioningclient = examples_env.Program('provisioningclient', 'provisioningclient.cpp') +if examples_env.get('WITH_TCP') == True: + cloudClient = examples_env.Program('cloudClient',['cloudClient.cpp', 'cloudAuth.cpp', 'cloudWrapper.cpp']) + src_dir = examples_env.get('SRC_DIR') svr_db_src_dir = src_dir + '/resource/provisioning/examples/' svr_db_build_dir = examples_env.get('BUILD_DIR') +'/resource/provisioning/examples/' @@ -100,5 +107,13 @@ svr_db_build_dir = examples_env.get('BUILD_DIR') +'/resource/provisioning/exampl clientjson = examples_env.Install(svr_db_build_dir, svr_db_src_dir + 'oic_svr_db_client.json') clientdat = examples_env.Install(svr_db_build_dir, svr_db_src_dir + 'oic_svr_db_client.dat') +if examples_env.get('WITH_TCP') == True: + clouddat = examples_env.Install(svr_db_build_dir, + svr_db_src_dir + 'cloud.dat') + rootcert = examples_env.Install(svr_db_build_dir, + svr_db_src_dir + 'rootca.crt') + Alias("cloud", [clouddat, rootcert, cloudClient]) + examples_env.AppendTarget("cloud") + Alias("examples", [provisioningclient, clientjson,clientdat]) examples_env.AppendTarget('examples') diff --git a/resource/provisioning/examples/cloud.dat b/resource/provisioning/examples/cloud.dat new file mode 100644 index 0000000000000000000000000000000000000000..d08f163c607b2deb208f860144fd8272d13be987 GIT binary patch literal 878 zcmbVK!A=4(5C!=aPbL%%yCwVy-rQ|xWtQ%CGt&h;g5Tl6$VGp`Z}2bt06A;B5JEHr z@X*XmXI|#L*S@PnncMcqD)SN9J?lgPFJC5Hr#UEB*Qk>#Bw$;U?>w&bm>?VXEUKQr zP01~CpNrWVMX?igI!B+d&>Nqy9 zfC^+rTV5QLv)r&N8g>k-r|rDhX(G{-Uej-yd+f>`wqlpK0Gjf|w0!>)uV>dJT^yK*S|K8xc)?9-@!9kw(+lko2rT>s4wn(d>fSB-3|b*hS1 z>in@qC*`7(YnY;f(>MN$;xQw1@OSk276LC?SqNZSij`|autcxVCThI0Gu=E}8_k8K Tdx6&B6y1Z+mHIm2*L?o~FxEIV literal 0 HcmV?d00001 diff --git a/resource/provisioning/examples/cloudAuth.cpp b/resource/provisioning/examples/cloudAuth.cpp new file mode 100644 index 0000000..3699aec --- /dev/null +++ b/resource/provisioning/examples/cloudAuth.cpp @@ -0,0 +1,462 @@ +/* ***************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * *****************************************************************/ + +#include "octypes.h" +#include "logger.h" +#include "payload_logging.h" +#include "ocstack.h" +#include "ocpayload.h" +//#include "psinterface.h" +#include "securevirtualresourcetypes.h" +#include "doxmresource.h" +#include "oic_malloc.h" +#include "oic_string.h" +#include "srmutility.h" +#include "pmutility.h" +#include "credresource.h" +#include "payload_logging.h" + +#include "utils.h" +#include "cloudAuth.h" + +#define TAG "cloudAuth" + +#define LOGIN_OK 4 + +#define MAX_URI_QUERY MAX_URI_LENGTH + MAX_QUERY_LENGTH + +typedef struct +{ + char *accesstoken; + char *refreshtoken; + char *tokentype; + long expiresin; + char *uid; + char *redirecturi; + char *certificate; + char *sid; +} sessionObject_t; + +static sessionObject_t sessionObject = {0,0,0,0,0,0,0,0}; + +extern void handleCB(void* ctx, OCStackResult result, void* data); + +/** + * Session free function + * + * @return OCStackResult application result + */ +void SessionFree() +{ + if (sessionObject.accesstoken) OICFree(sessionObject.accesstoken); + if (sessionObject.refreshtoken) OICFree(sessionObject.refreshtoken); + if (sessionObject.tokentype) OICFree(sessionObject.tokentype); + if (sessionObject.uid) OICFree(sessionObject.uid); + if (sessionObject.redirecturi) OICFree(sessionObject.redirecturi); + if (sessionObject.certificate) OICFree(sessionObject.certificate); + if (sessionObject.sid) OICFree(sessionObject.sid); + + memset(&sessionObject, 0, sizeof(sessionObject_t)); +} + +/** + * Session init function + * + * @param[in] sessionObject session data + * @return OCStackResult application result + */ +OCStackResult SessionInit() +{ + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + SessionFree(); + + OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__); + + return OC_STACK_OK; +} + +/** + * Session parse payload + * + * @param[in] payload + * @param[in] sessionObject session data + * @return OCStackResult application result + */ +OCStackResult SessionParsePayload(OCRepPayload *payload) +{ + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + VERIFY_NON_NULL(TAG, payload, ERROR); + + SessionInit(); + + if (!OCRepPayloadGetPropString(payload, OC_RSRVD_ACCESS_TOKEN, + &sessionObject.accesstoken)) + { + OIC_LOG(ERROR, TAG, "Can't get: accesstoken"); + } + if (!OCRepPayloadGetPropString(payload, OC_RSRVD_REFRESH_TOKEN, + &sessionObject.refreshtoken)) + { + OIC_LOG(ERROR, TAG, "Can't get: refreshtoken"); + } + if (!OCRepPayloadGetPropString(payload, OC_RSRVD_TOKEN_TYPE, + &sessionObject.tokentype)) + { + OIC_LOG(ERROR, TAG, "Can't get: tokentype"); + } + if (!OCRepPayloadGetPropInt(payload, OC_RSRVD_EXPIRES_IN, + &(sessionObject.expiresin))) + { + OIC_LOG(ERROR, TAG, "Can't get: expiresin"); + } + if (!OCRepPayloadGetPropString(payload, OC_RSRVD_USER_UUID, + &sessionObject.uid)) + { + OIC_LOG(ERROR, TAG, "Can't get: uid"); + } + if (!OCRepPayloadGetPropString(payload, OC_RSRVD_REDIRECT_URI, + &sessionObject.redirecturi)) + { + OIC_LOG(ERROR, TAG, "Can't get: redirecturi"); + } + if (!OCRepPayloadGetPropString(payload, OC_RSRVD_CERTIFICATE, + &sessionObject.certificate)) + { + OIC_LOG(ERROR, TAG, "Can't get: certificate"); + } + if (!OCRepPayloadGetPropString(payload, OC_RSRVD_SUBJECT_ID, + &sessionObject.sid)) + { + OIC_LOG(ERROR, TAG, "Can't get: sid"); + } + + OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__); +exit: + return OC_STACK_OK; +} + +/** + * Cloud login handler + * + * @param[in] response login response + */ +OCStackApplicationResult handleCloudSignUpResponse(void *ctx, + OCDoHandle handle, + OCClientResponse *response) +{ + OC_UNUSED(ctx); + OC_UNUSED(handle); + + if (!response) + { + OIC_LOG(ERROR, TAG, "Received NULL response!"); + goto exit; + } + + if (response->payload) + { + OIC_LOG(ERROR, TAG, "Payload received"); + OIC_LOG_PAYLOAD(DEBUG, response->payload); + } + + if (response->result != LOGIN_OK) + { + OIC_LOG_V(ERROR, TAG, "Login error: %d",response->result); + } + else + { + OIC_LOG(DEBUG, TAG, "Login successful"); + SessionParsePayload((OCRepPayload*)response->payload); + } +exit: + handleCB(NULL, OC_STACK_OK, NULL); + return OC_STACK_DELETE_TRANSACTION; +} + +/** + * Cloud authentication + * + * @param[in] endPoint cloud host and port + * @param[in] authProvider auth provider + * @param[in] authToken token + * @return OCStackResult application result + */ +OCStackResult +CloudSignUp(OCDevAddr *endPoint, + const char *authProvider, + const char *authToken, + OCClientResponseHandler response) +{ + char uri[MAX_URI_LENGTH] = { 0 }; + + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + if (!endPoint || !authProvider || !authToken) + { + OIC_LOG(ERROR, TAG, "Some of the input params are NULL"); + return OC_STACK_INVALID_PARAM; + } + + char *deviceId = getDeviceId(); + if (!deviceId) + { + OIC_LOG(ERROR, TAG, "Can't get the device id"); + return OC_STACK_ERROR; + } + + snprintf(uri, MAX_URI_LENGTH, DEFAULT_QUERY, + endPoint->addr, endPoint->port, OC_RSRVD_ACCOUNT_URI); + + OIC_LOG_V(DEBUG, TAG, "Query created: %s", uri); + + OCCallbackData cbData; + memset(&cbData, 0, sizeof(OCCallbackData)); + cbData.cb = response; + cbData.context = (void*)handleCloudSignUpResponse; + + OCRepPayload *payload = OCRepPayloadCreate(); + if (!payload) + { + OIC_LOG(ERROR, TAG, "Failed to memory allocation"); + return OC_STACK_NO_MEMORY; + } + + OCRepPayloadSetPropString(payload, OC_RSRVD_DEVICE_ID, deviceId); + OCRepPayloadSetPropString(payload, OC_RSRVD_AUTHPROVIDER, OICStrdup(authProvider)); + OCRepPayloadSetPropString(payload, OC_RSRVD_AUTHCODE, OICStrdup(authToken)); + + return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload, + CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0); +} + +/** + * Cloud Sign In handler + * + * @param[in] OCClientResponse cloud response + * @return OCStackApplicationResult application result + */ +OCStackApplicationResult handleCloudSignInResponse(void *ctx, + OCDoHandle handle, + OCClientResponse *response) +{ + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + OC_UNUSED(ctx); + OC_UNUSED(handle); + + if (!response) + { + OIC_LOG(ERROR, TAG, "Received NULL response!"); + goto exit; + } + + if (response->payload) + { + OIC_LOG(ERROR, TAG, "Payload received"); + OIC_LOG_PAYLOAD(DEBUG, response->payload); + } + + if (response->result < 4 && response->payload) + { + OIC_LOG_V(ERROR, TAG, "Sign In error: result: %d, payload exist: %s", + response->result, response->payload ? "yes" : "no"); + goto exit; + } + + if (!OCRepPayloadGetPropString((OCRepPayload*)response->payload, OC_RSRVD_USER_UUID, + &(sessionObject.uid))) + { + OIC_LOG(ERROR, TAG, "Can't get: uid"); + } + + if (!OCRepPayloadGetPropInt((OCRepPayload*)response->payload, OC_RSRVD_EXPIRES_IN, + &(sessionObject.expiresin))) + { + OIC_LOG(ERROR, TAG, "Cann't get: expiresin"); + } + + OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__); + +exit: + handleCB(NULL, OC_STACK_OK, NULL); + return OC_STACK_DELETE_TRANSACTION; +} + +/** + * Sign In request function + * + * @param[in] endPoint cloud host and port + * @return OCStackResult application result + */ +OCStackResult CloudSignIn(OCDevAddr *endPoint, OCClientResponseHandler response) +{ + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + if (!endPoint) + { + OIC_LOG_V(ERROR, TAG, "%s: endPoint is NULL",__func__); + return OC_STACK_INVALID_PARAM; + } + + if (!sessionObject.uid) + { + OIC_LOG_V(ERROR, TAG, "%s: UID is missing. Please run Sign Up first",__func__); + return OC_STACK_ERROR; + } + + if (!sessionObject.accesstoken) + { + OIC_LOG_V(ERROR, TAG, "%s: accesstoken is missing. Please run Sign Up first",__func__); + return OC_STACK_ERROR; + } + + char *deviceId = getDeviceId(); + if (!deviceId) + { + OIC_LOG(ERROR, TAG, "Can't get the device id"); + return OC_STACK_ERROR; + } + + OCRepPayload* payload = OCRepPayloadCreate(); + if (NULL == payload) + { + OIC_LOG(ERROR, TAG, "Failed to memory allocation"); + return OC_STACK_NO_MEMORY; + } + + OCRepPayloadSetPropString(payload, OC_RSRVD_USER_UUID, sessionObject.uid); + OCRepPayloadSetPropString(payload, OC_RSRVD_DEVICE_ID, deviceId); + OCRepPayloadSetPropString(payload, OC_RSRVD_ACCESS_TOKEN, + sessionObject.accesstoken); + OCRepPayloadSetPropBool(payload, OC_RSRVD_LOGIN, true); + + char uri[MAX_URI_QUERY] = { 0, }; + snprintf(uri, MAX_URI_QUERY, DEFAULT_QUERY, + endPoint->addr, endPoint->port, + OC_RSRVD_ACCOUNT_SESSION_URI); + + OCCallbackData cbData; + memset(&cbData, 0, sizeof(OCCallbackData)); + cbData.cb = response; + cbData.context = (void*)handleCloudSignInResponse; + + return OCDoResource(NULL, OC_REST_POST, uri, NULL, + (OCPayload *)payload, + CT_ADAPTER_TCP, + OC_LOW_QOS, &cbData, NULL, 0); +} +/** + * Cloud Sign Out handler + * + * @param[in] OCClientResponse cloud response + * @return OCStackApplicationResult application result + */ +OCStackApplicationResult handleCloudSignOutResponse(void *ctx, + OCDoHandle handle, + OCClientResponse *response) +{ + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + OC_UNUSED(ctx); + OC_UNUSED(handle); + + if (!response) + { + OIC_LOG(ERROR, TAG, "Received NULL response!"); + goto exit; + } + + if (response->payload) + { + OIC_LOG(ERROR, TAG, "Payload received"); + OIC_LOG_PAYLOAD(DEBUG, response->payload); + } + + if (response->result < 4 && response->payload) + { + OIC_LOG_V(ERROR, TAG, "Sign Out error"); + return OC_STACK_DELETE_TRANSACTION; + } + else + { + OIC_LOG_V(ERROR, TAG, "Sign Out OK"); + } + + SessionFree(); + + OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__); + +exit: + handleCB(NULL, OC_STACK_OK, NULL); + return OC_STACK_DELETE_TRANSACTION; +} +/** + * Sign In request function + * + * @param[in] endPoint cloud host and port + * @return OCStackResult application result + */ +OCStackResult CloudSignOut(OCDevAddr *endPoint, OCClientResponseHandler response) +{ + OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__); + + if (!endPoint) + { + OIC_LOG_V(ERROR, TAG, "%s: endPoint is NULL",__func__); + return OC_STACK_INVALID_PARAM; + } + + char *deviceId = getDeviceId(); + if (!deviceId) + { + OIC_LOG(ERROR, TAG, "Cann't get the device id"); + return OC_STACK_ERROR; + } + + OCRepPayload* payload = OCRepPayloadCreate(); + if (!payload) + { + OIC_LOG(ERROR, TAG, "Failed to memory allocation"); + return OC_STACK_NO_MEMORY; + } + + OCRepPayloadSetPropString(payload, OC_RSRVD_DEVICE_ID, deviceId); + OCRepPayloadSetPropString(payload, OC_RSRVD_ACCESS_TOKEN, + sessionObject.accesstoken); + OCRepPayloadSetPropBool(payload, OC_RSRVD_LOGIN, false); + + char uri[MAX_URI_QUERY] = { 0, }; + snprintf(uri, MAX_URI_QUERY, DEFAULT_QUERY, + endPoint->addr, endPoint->port, + OC_RSRVD_ACCOUNT_SESSION_URI); + + OCCallbackData cbData; + memset(&cbData, 0, sizeof(OCCallbackData)); + cbData.cb = response; + cbData.context = (void*)handleCloudSignOutResponse; + + return OCDoResource(NULL, OC_REST_POST, uri, NULL, + (OCPayload *)payload, + CT_ADAPTER_TCP, + OC_LOW_QOS, &cbData, NULL, 0); +} + diff --git a/resource/provisioning/examples/cloudAuth.h b/resource/provisioning/examples/cloudAuth.h new file mode 100644 index 0000000..6a578ba --- /dev/null +++ b/resource/provisioning/examples/cloudAuth.h @@ -0,0 +1,90 @@ +/* ***************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * *****************************************************************/ +#ifndef CLOUD_AUTH_H +#define CLOUD_AUTH_H + +/** + * Sends Sign UP request to cloud + * + * @param[in] endPoint peer endpoint + * @param[in] authProvider authentication provider + * @param[in] authToken authentication token + * @param[in] response response callback + * @return OCStackResult application result + */ +OCStackResult CloudSignUp(OCDevAddr *endPoint, const char *authProvider, const char *authToken, + OCClientResponseHandler response); + +/** + * Sends Sign IN request to cloud + * + * @param[in] endPoint peer endpoint + * @param[in] response response callback + * @return OCStackResult application result + */ +OCStackResult CloudSignIn(OCDevAddr *endPoint, OCClientResponseHandler response); + +/** + * Sends Sign IN request to cloud + * + * @param[in] endPoint peer endpoint + * @param[in] response response callback + * @return OCStackResult application result + */ +OCStackResult CloudSignOut(OCDevAddr *endPoint, OCClientResponseHandler response); + +/** + * Sends Sign Up request to cloud + * + * @param[in] ctx context + * @param[in] handle handle + * @param[in] response response from peer + * @return OCStackApplicationResult application result + */ +OCStackApplicationResult handleCloudSignUpResponse(void *ctx, + OCDoHandle handle, + OCClientResponse *response); + +/** + * Sends Sign In request to cloud + * + * @param[in] ctx context + * @param[in] handle handle + * @param[in] response response from peer + * @return OCStackApplicationResult application result + */ +OCStackApplicationResult handleCloudSignInResponse(void *ctx, + OCDoHandle handle, + OCClientResponse *response); + +/** + * Sends Sign Out request to cloud + * + * @param[in] ctx context + * @param[in] handle handle + * @param[in] response response from peer + * @return OCStackApplicationResult application result + */ +OCStackApplicationResult handleCloudSignOutResponse(void *ctx, + OCDoHandle handle, + OCClientResponse *response); + + +#endif // CLOUD_AUTH_H diff --git a/resource/provisioning/examples/cloudClient.cpp b/resource/provisioning/examples/cloudClient.cpp new file mode 100644 index 0000000..c4b5038 --- /dev/null +++ b/resource/provisioning/examples/cloudClient.cpp @@ -0,0 +1,524 @@ +//****************************************************************** +// +// Copyright 2016 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#include +#include +#include + +#include "ocstack.h" +#include "logger.h" +#include "camutex.h" +#include "cathreadpool.h" +#include "ocpayload.h" +#include "payload_logging.h" +#include "ocprovisioningmanager.h" + +#include "utils.h" +#include "cloudAuth.h" +#include "cloudWrapper.h" +#include "OCApi.h" +#include "OCCloudProvisioning.h" + +#ifdef __unix__ +#include //for unlink +#endif + +#define TAG "cloudClient" +using namespace OC; + +#define DEFAULT_HOST "10.113.68.85"//"127.0.0.1" +#define DEFAULT_PORT OC_MULTICAST_PORT +#define DEFAULT_DEVICEID "6A757374-776F-726B-4465-765575696430" +#define DEFAULT_USERID "6A757374-776F-726B-4465-765575696430" +#define DEFAULT_AUTH_PROVIDER "github" +#define DEFAULT_DB_FILE "./cloud.dat" +#define DEFAULT_RESPONSE_WAIT_TIME (10 * 1000000) //10s + +#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" + +static bool fExit = false; + +static OCDevAddr endPoint; +static char token[1024]; +static char authProvider[1024]; +static char *fname = DEFAULT_DB_FILE; +static uint64_t timeout; +static uint16_t g_credId = 0; + +ca_cond cond; +ca_mutex mutex; +std::string ip(""); +OCCloudProvisioning g_cloudProv(ip, 0); + +typedef enum { + SIGN_UP = 1, + SIGN_IN = 2, + SIGN_OUT = 3, + + HOST = 4, + PORT = 5, + DB_FILE = 6, + AUTH_PROVIDER = 7, + USE_RSA = 8, + SAVE_TRUST_CERT = 9, + USE_SECURE_CONN = 10, + + CSR_SIGN = 19, + + CRL_GET = 20, + CRL_POST = 21, + + ACL_ID_CREATE = 30, + ACL_ID_GET_BY_DEVICE = 31, + ACL_ID_DELETE = 32, + + ACL_INDIVIDUAL_GET_INFO = 40, + ACL_INDIVIDUAL_UPDATE_ACE = 41, + ACL_INDIVIDUAL_DELETE = 42, + + ACL_GROUP_CREATE = 50, + ACL_GROUP_FIND = 51, + ACL_GROUP_JOIN = 52, + ACL_GROUP_OBSERVE= 53, + ACL_GROUP_DELETE = 54, + + ACL_GROUP_SHARE_DEVICE = 60, + ACL_GROUP_DELETE_DEVICE = 61, + ACL_GROUP_GET_INFO = 62, + + ACL_POLICY_CHECK_REQUEST = 70, + + ACL_GROUP_INVITE_USER = 80, + ACL_GROUP_GET_INVITE = 81, + ACL_GROUP_DELETE_INVITE = 82, + ACL_GROUP_CANCEL_INVITE = 83, + + EXIT = 99 +}CloudRequest; + +void printMenu() +{ + printf("************************************************************\n"); + printf("****************** Cloud Client Requests *******************\n"); + printf("************************************************************\n"); + printf("** AUTHORIZATION\n"); + printf("** %d - Sign Up request\n", SIGN_UP); + printf("** %d - Sign In request\n", SIGN_IN); + printf("** %d - Sign Out request\n", SIGN_OUT); + + printf("** SETTINGS \n"); + printf("** %d - Change default host\n", HOST); + printf("** %d - Change default port\n", PORT); + printf("** %d - Change default database filename\n", DB_FILE); + printf("** %d - Change default auth provider\n", AUTH_PROVIDER); + printf("** %d - Change TLS cipher suite to RSA\n", USE_RSA); + printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT); + printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN); + + printf("** CERTIFICATE REQUEST\n"); + printf("** %d - Certificate Request\n", CSR_SIGN); + + printf("** CRL\n"); + printf("** %d - CRL GET Request\n", CRL_GET); + printf("** %d - CRL POST Request\n", CRL_POST); + + printf("** ACL MANAGER\n"); + printf("** %d - ACL id create Request\n", ACL_ID_CREATE); + printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE); + printf("** %d - ACL id delete Request\n", ACL_ID_DELETE); + + printf("** ACL INDIVIDUAL\n"); + printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO); + printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE); + printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE); + + printf("** ACL GROUP MANAGER\n"); + printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE); + printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND); + printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN); + printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE); + printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE); + + printf("** ACL INDIVIDUAL GROUP\n"); + printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE); + printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE); + printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO); + + printf("** ACL POLICY ENFORCEMENT\n"); + printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST); + + printf("** ACL MEMBER INVITATION\n"); + printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER); + printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE); + printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE); + printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE); + + printf("** EXIT\n"); + printf("** %d - Exit cloud client\n\n", EXIT); + printf("************************************************************\n"); + + printf(">> Enter Menu number:\n"); +} + +/** + * This is default callback to all requests + * Used to sync with main menu + * + * @param[in] ctx context + * @param[in] result result + * @param[in] data data + */ +void handleCB(void* ctx, OCStackResult result, void* data) +{ + OC_UNUSED(ctx); + OC_UNUSED(result); + OC_UNUSED(data); + + ca_mutex_lock(mutex); + ca_cond_signal(cond); + ca_mutex_unlock(mutex); +} + +void handleCB1(OCStackResult result, void *data) +{ + OC_UNUSED(result); + OC_UNUSED(data); + + ca_mutex_lock(mutex); + ca_cond_signal(cond); + ca_mutex_unlock(mutex); +} + +void handleCB2(OCStackResult result, std::string data) +{ + OC_UNUSED(result); + OC_UNUSED(data); + + ca_mutex_lock(mutex); + ca_cond_signal(cond); + ca_mutex_unlock(mutex); +} + +static int saveTrustCert(void) +{ + OCStackResult res = OC_STACK_ERROR; + OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR"); + + ByteArray trustCertChainArray = {0, 0}; + + FILE *fp = fopen("rootca.crt", "rb+"); + + if (fp) + { + size_t fsize; + if (fseeko(fp, 0, SEEK_END) == 0 && (fsize = ftello(fp))) + { + trustCertChainArray.data = (uint8_t*)OICCalloc(1, fsize+1); + trustCertChainArray.len = fsize+1; + if (NULL == trustCertChainArray.data) + { + OIC_LOG(ERROR,TAG,"OICCalloc"); + fclose(fp); + return res; + } + rewind(fp); + fsize = fread(trustCertChainArray.data, 1, fsize, fp); + fclose(fp); + } + } + OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len); + + res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId); + + if(OC_STACK_OK != res) + { + OIC_LOG(ERROR, TAG, "OCSaveTrustCertChainBin API error"); + return res; + } + OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId); + + return res; +} + +static void userRequests(void *data) +{ + (void) data; + //defaults + memset(token, 0, sizeof(token)); + memset(authProvider, 0, sizeof(authProvider)); + strncpy(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)); + memset(&endPoint, 0, sizeof(endPoint)); + strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr)); + endPoint.port = DEFAULT_PORT; + + mutex = ca_mutex_new(); + cond = ca_cond_new(); + + while (false == fExit) + { + OCStackResult res = OC_STACK_ERROR; + timeout = DEFAULT_RESPONSE_WAIT_TIME; + //startup report + printf("-----------------------------------------------------------\n"); + printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port); + printf("via auth provider: %s\n", authProvider); + printf("srv file: %s\n", fname); + printf("CoAP prefix: %s\n", DEFAULT_PREFIX); + printf("-----------------------------------------------------------\n"); + + printMenu(); + + int request = 0; + scanf("%d", &request); + + switch (request) + { + case SIGN_UP: + if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider))) + { + printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK); + } + readString(token, sizeof(token), "auth token", "check link above"); + res = CloudSignUp(&endPoint, authProvider, token, handleCloudSignUpResponse); + break; + case SIGN_IN: + res = CloudSignIn(&endPoint, handleCloudSignInResponse); + break; + case SIGN_OUT: + res = CloudSignOut(&endPoint, handleCloudSignOutResponse); + break; + case HOST: + { + readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST); + std::string str(endPoint.addr); + g_cloudProv.setIpAddr(str); + break; + } + case PORT: + { + char example[8]; + snprintf(example, sizeof(example), "%d", DEFAULT_PORT); + int tmp = 0; + readInteger(&tmp, "port number", example); + endPoint.port = tmp; + g_cloudProv.setPort((uint16_t)tmp); + } + break; + case CRL_GET: + res = OCWrapperGetCRL( g_cloudProv, handleCB1); + break; + case CRL_POST: + res = OCWrapperPostCRL( g_cloudProv, handleCB1); + break; + case ACL_GROUP_CREATE: + res = OCWrapperAclCreateGroup(&endPoint, handleCB); + break; + case ACL_GROUP_FIND: + res = OCWrapperAclFindMyGroup(&endPoint, handleCB); + break; + case ACL_GROUP_DELETE: + res = OCWrapperAclDeleteGroup(&endPoint, handleCB); + break; + case ACL_GROUP_JOIN: + res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB); + break; + case ACL_GROUP_OBSERVE: + res = OCWrapperAclObserveGroup(&endPoint, handleCB); + break; + case ACL_GROUP_SHARE_DEVICE: + res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB); + break; + case ACL_GROUP_DELETE_DEVICE: + res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB); + break; + case ACL_GROUP_GET_INFO: + res = OCWrapperAclGroupGetInfo(&endPoint, handleCB); + break; + case ACL_GROUP_INVITE_USER: + res = OCWrapperAclInviteUser(&endPoint, handleCB); + break; + case ACL_GROUP_GET_INVITE: + res = OCWrapperAclGetInvitation(&endPoint, handleCB); + break; + case ACL_GROUP_DELETE_INVITE: + res = OCWrapperAclDeleteInvitation(&endPoint, handleCB); + break; + case ACL_GROUP_CANCEL_INVITE: + res = OCWrapperAclCancelInvitation(&endPoint, handleCB); + break; + case ACL_POLICY_CHECK_REQUEST: + res = OCWrapperAclPolicyCheck(&endPoint, handleCB); + break; + case ACL_ID_GET_BY_DEVICE: + res = OCWrapperAclIdGetByDevice( g_cloudProv, handleCB2); + break; + case ACL_ID_CREATE: + res = OCWrapperAclIdCreate(&endPoint, handleCB); + break; + case ACL_ID_DELETE: + res = OCWrapperAclIdDelete(&endPoint, handleCB); + break; + case ACL_INDIVIDUAL_GET_INFO: + res = OCWrapperAclIndividualGetInfo( g_cloudProv, handleCB1); + break; + case ACL_INDIVIDUAL_UPDATE_ACE: + res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB); + break; + case ACL_INDIVIDUAL_DELETE: + res = OCWrapperAclIndividualDelete(&endPoint, handleCB); + break; + case CSR_SIGN: + res = OCWrapperCertificateIssueRequest( g_cloudProv, handleCB1); + break; + case USE_RSA: +// CASelectCipherSuite(0x35, CA_ADAPTER_TCP); + break; + case SAVE_TRUST_CERT: + saveTrustCert(); + break; + case USE_SECURE_CONN: + { + int tmp = 0; + readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure"); + setCoapPrefix(0 == tmp ? false : true); + } + break; + case EXIT: + ca_mutex_free(mutex); + ca_cond_free(cond); + fExit = true; + break; + default: + printf(">> Entered Wrong Menu Number. Please Enter Again\n\n"); + break; + } + + //if requests were sent then wait response + if (res == OC_STACK_OK) + { + ca_mutex_lock(mutex); + ca_cond_wait_for(cond, mutex, timeout); + ca_mutex_unlock(mutex); + } + } + + +} + +FILE* server_fopen(const char *path, const char *mode) +{ + OC_UNUSED(path); + return fopen(fname, mode); +} + +/** + * Check file accessibility + * + * @param[in] name file path + * @return true if check was successful + */ +static bool checkConfig(const char *name) +{ + FILE* file = fopen(name, "rb"); + + if (file) + { + fclose(file); + return true; + } + return false; +} + +static void printUsage(char *name) +{ + printf("Wrong arguments count!\n"); + printf("Usage : %s \n", name); + printf("Examples : 1) %s 2) %s cloud.dat\n", name, name); +} + +//============================================================== +int main(int argc, char *argv[]) +{ + OC_UNUSED(argc); + OC_UNUSED(argv); + + if (2 == argc) + { + fname = argv[1]; + + if (!checkConfig(fname)) + { + OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname); + return -1; + } + } + else if (argc > 2) + { + printUsage(argv[0]); + } + + //Initialize Persistent Storage for SVR database + OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink}; + + OCRegisterPersistentStorageHandler(&ps); + + OCMode stackMode = OC_CLIENT_SERVER; + if (OCInit(NULL, 0, stackMode) != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStack init error, exit\n"); + return 1; + } + + ca_thread_pool_t g_threadPoolHandle = NULL; + CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "thread pool initialize error."); + return res; + } + + res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, NULL); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "thread pool add task error."); + goto error; + } + + while(false == fExit) + { + if (OCProcess() != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n"); + return 2; + } + } + + if (OCStop() != OC_STACK_OK) + { + OIC_LOG(ERROR, TAG, "OCStop process error\n"); + } + + error: + if (g_threadPoolHandle) + { + ca_thread_pool_free(g_threadPoolHandle); + } + + return 0; +} diff --git a/resource/provisioning/examples/cloudWrapper.cpp b/resource/provisioning/examples/cloudWrapper.cpp new file mode 100644 index 0000000..493ff47 --- /dev/null +++ b/resource/provisioning/examples/cloudWrapper.cpp @@ -0,0 +1,615 @@ + +#include "logger.h" +#include "occloudprovisioning.h" +#include "OCCloudProvisioning.h" +#include "oic_malloc.h" +#include "oic_string.h" +#include "utils.h" + +#define TAG "CLOUD-WRAPPER" + +#define MAX_ID_LENGTH (64) +#define MAX_STRING_LENGTH (256) + +#define UUID_EXAMPLE_1 "9cfbeb8e-5a1e-4d1c-9d01-2ae6fdb" +#define UUID_EXAMPLE_2 "123e4567-e89b-12d3-a456-4266554" +#define UUID_EXAMPLE_3 "987e6543-e21b-12d3-a456-4266554" +#define SUBJECT_ID_EXAMPLE "72616E64-5069-6E44-6576-557569643030" + +#define ACL_ID_EXAMPLE "0f3d9f7fe5491d54077d" +#define ACE_ID_EXAMPLE "a0001" + +#define ID_EXAMPLE_1 "78f98b4f25f21e2487e8" +#define ID_EXAMPLE_2 "6caa7009386290fd3681" + +#define RESOURCE_URI_EXAMPLE "/a/light/0" +#define RESOURCE_TYPE_EXAMPLE "core.light" +#define INTERFACE_EXAMPLE "oic.if.baseline" + +//in case of optional parameters absence should be sent NULL +#define OPTIONAL(str) (str[0] ? str : NULL) + +using namespace OC; + +static bool readOptional(const char* description) +{ + if (NULL == description) + { + return false; + } + + printf("Do you want to Enter %s (y/n):\n", description); + char choice = 0; + + while(1) + { + scanf("%c", &choice); + getchar(); + + switch (choice) + { + case 'y': return true; + case 'n': return false; + default: printf("Wrong value entered. Please press 'y' or 'n'\n"); + } + } + return false; +} + +/** + * Read user input (expect string value) + * + * @param[out] item string item to fill + * @param[in] length max allowed string length + * @param[in] description item description + * @param[in] example item example + */ +void readString(char* item, int length, const char* description, const char* example) +{ + printf("Enter %s (f.e. %s):\n", description, example); + char temp[8] = { 0 }; + snprintf(temp, sizeof(temp), "%%%ds", length - 1); + scanf(temp, item); + getchar(); +} + +/** + * Read user input (expect string value, but it is optional and can be skipped by user) + * + * @param[out] item string item to fill + * @param[in] length max allowed string length + * @param[in] description item description + * @param[in] example item example + */ +static void readOptionalString(char* item, int length, const char* description, const char* example) +{ + if (readOptional(description)) + { + readString(item, length, description, example); + } +} + +/** + * Read user input (expect integer value) + * + * @param[out] item integer item to fill + * @param[in] description item description + * @param[in] example item example + */ +void readInteger(int* item, const char* description, const char* example) +{ + printf("Enter %s (f.e. %s):\n", description, example); + scanf("%d", item); + getchar(); +} + +/** + * Read user input (expect array of strings) + * + * @param[out] list array of strings structure + * @param[in] length max allowed array item length + * @param[in] description whole array description + * @param[in] example array item example + */ +static void readStringArray(stringArray_t *list, int length, const char* description, const char* example) +{ + int i = 0; + int count = 0; + char hint[MAX_STRING_LENGTH] = { 0 }; + + snprintf(hint, sizeof(hint), "%s items count", description); + readInteger(&count, hint, "2"); + + char **item = NULL; + + if (0 == count) + { + return; + } + + item = (char**)OICCalloc(count, sizeof(char*)); + + if (NULL == item) + { + goto no_memory; + } + + for (i = 0; i < count; i++) + { + item[i] = (char*)OICCalloc(length, sizeof(char)); + + if (NULL == item[i]) + { + goto no_memory; + } + + snprintf(hint, sizeof(hint), "%s %d item", description, i + 1); + readString(item[i], length, hint, example); + } + list->array = item; + list->length = count; + return; + +no_memory: + //free already allocated memory here + for (int k = 0; k < i; k++) + { + OICFree(item[k]); + } + OICFree(item); +} + +/** + * Read user input (expect array of strings) + * It is optional and can be skipped by user. + * + * @param[out] list array of strings structure + * @param[in] length max allowed array item length + * @param[in] description whole array description + * @param[in] example array item example + */ +static void readOptionalStringArray(stringArray_t *list, int length, const char* description, const char* example) +{ + if (readOptional(description)) + { + readStringArray(list, length, description, example); + } +} + +/** + * Copies whole binary file to crl variable + * + * @param[in] list array of strings structure + * @param[out] crl byte array to fill + * @return negative error code + * */ +static int ReadFile(const char *name, OCByteString *crl) +{ + FILE *file = NULL; + int length = 0; + uint8_t *buffer = NULL; + int result = 1; + size_t realLen = 0; + + //Open file + file = fopen(name, "rb"); + if (!file) + { + OIC_LOG_V(ERROR, TAG, "Unable to open file %s", name); + return result; + } + + //Get file length + result = fseek(file, 0, SEEK_END); + if (result) + { + OIC_LOG(ERROR, TAG, "Failed to SEEK_END"); + goto exit; + } + + length = ftell(file); + if (length < 0) + { + OIC_LOG(ERROR, TAG, "Failed to ftell"); + goto exit; + } + + result = fseek(file, 0, SEEK_SET); + if (result) + { + OIC_LOG(ERROR, TAG, "Failed to SEEK_SET"); + goto exit; + } + + //Allocate memory + buffer = (uint8_t *)malloc(length); + if (!buffer) + { + OIC_LOG(ERROR, TAG, "Failed to allocate buffer"); + goto exit; + } + + //Read file contents into buffer + realLen = fread(buffer, length, 1, file); + if (realLen != (size_t)length) + { + OIC_LOG_V(ERROR, TAG, "Length mismatch: read %zu instead of %d bytes", realLen, length); + goto exit; + } + + crl->bytes = buffer; + crl->len = length; + + result = 0; +exit: + fclose(file); + return 0; +} + +OCStackResult OCWrapperCertificateIssueRequest(OCCloudProvisioning& ptr, ResponseCallBack callback) +{ + return ptr.requestCertificate(callback); +} + +OCStackResult OCWrapperGetCRL(OCCloudProvisioning& ptr, ResponseCallBack callback) +{ + return ptr.getCRL(callback); +} + +OCStackResult OCWrapperPostCRL(OCCloudProvisioning& ptr, ResponseCallBack callback) +{ + OCStackResult result = OC_STACK_ERROR; + OCByteString crlData = {0, 0}; + char filename[64] = {0}; + char thisUpdate[16] = { 0 }; + char nextUpdate[16] = { 0 }; + stringArray_t serialNumbers = {0, 0}; + stringArray_t *rcsn = 0; + OCByteString *crl = 0; + + readString(thisUpdate, sizeof(thisUpdate), "Crl's thisUpdate value", "20160727000000"); + readString(nextUpdate, sizeof(nextUpdate), "Crl's nextUpdate value", "20161027000000"); + readOptionalStringArray(&serialNumbers, 16, "Revoked serial numbers", "1234"); + + if (NULL == serialNumbers.array) + { + readString(filename, sizeof(filename), + "filename from which binary Crl in DER format will be read", "crl"); + + if (ReadFile(filename, &crlData)) + { + printf("Can't read crl from file %s\n", filename); + goto exit; + } + } + rcsn = serialNumbers.array? &serialNumbers : NULL; + crl = crlData.bytes? &crlData : NULL; + + result = ptr.postCRL(thisUpdate, nextUpdate, crl, rcsn, + callback); +exit: + clearStringArray(&serialNumbers); + OICFree(crlData.bytes); + + return result; +} + +OCStackResult OCWrapperAclIdGetByDevice(OCCloudProvisioning& ptr, AclIdResponseCallBack callback) +{ + char di[MAX_ID_LENGTH] = { 0 }; + + readString(di, sizeof(di), "device id", UUID_EXAMPLE_1); + + return ptr.getAclIdByDevice(di, callback); +} + +OCStackResult OCWrapperAclIdCreate(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char oid[MAX_ID_LENGTH] = { 0 }; + char di[MAX_ID_LENGTH] = { 0 }; + + readString(oid, sizeof(oid), "owner id", UUID_EXAMPLE_2); + readString(di, sizeof(di), "device id", UUID_EXAMPLE_1); + + return OCCloudAclIdCreate(NULL, oid, di, endPoint, callback); +} + +OCStackResult OCWrapperAclIdDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char aclid[MAX_ID_LENGTH] = { 0 }; + + readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE); + + return OCCloudAclIdDelete(NULL, aclid, endPoint, callback); +} + +OCStackResult OCWrapperAclIndividualGetInfo(OCCloudProvisioning& ptr, ResponseCallBack callback) +{ + char aclid[MAX_ID_LENGTH] = { 0 }; + + readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE); + + return ptr.getIndividualAclInfo(aclid, callback); +} + +OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + OCStackResult result = OC_STACK_NO_MEMORY; + int i = 0, j = 0; + + char aclid[MAX_ID_LENGTH] = { 0 }; + readString(aclid, sizeof(aclid), "ace id", ACL_ID_EXAMPLE); + + int acllist_count = 0; + readInteger(&acllist_count, "acl list count", "1"); + + cloudAce_t *aces = (cloudAce_t*)OICCalloc(acllist_count, sizeof(cloudAce_t)); + if (!aces) + { + OIC_LOG(ERROR, TAG, "Can't allocate memory for aces"); + goto exit; + } + + for (i = 0; i < acllist_count; i++) + { + cloudAce_t *ace = &aces[i]; + if (i != acllist_count - 1) ace->next = &aces[i + 1]; + + char aceid[MAX_ID_LENGTH] = { 0 }; + char subjectuuid[MAX_ID_LENGTH] = { 0 }; + int stype = 0; + int permission = 0; + + readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE); + readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE); + readInteger(&stype, "subject type", "0 – Device, 1 – User, 2 - Group"); + readInteger(&permission, "permission", "6"); + + ace->aceId = OICStrdup(aceid); + ace->stype = stype; + ace->permission = permission; + memcpy(&ace->subjectuuid, subjectuuid, sizeof(OicUuid_t)); + + int reslist_count = 0; + readInteger(&reslist_count, "resources list count", "1"); + + ace->resources = (OicSecRsrc_t*)OICCalloc(reslist_count, sizeof(OicSecRsrc_t)); + if (!ace->resources) + { + OIC_LOG(ERROR, TAG, "Can't allocate memory for resources"); + goto exit; + } + + for (j = 0; j < reslist_count; j++) + { + OicSecRsrc_t *res = &ace->resources[j]; + if (j != reslist_count - 1) res->next = &ace->resources[j + 1]; + + char href[32] = { 0 }; + readString(href, sizeof(href), "href", RESOURCE_URI_EXAMPLE); + + stringArray_t rt = {0, 0}; + readStringArray(&rt, MAX_ID_LENGTH, "resource type", RESOURCE_TYPE_EXAMPLE); + + stringArray_t _if = {0, 0}; + readStringArray(&_if, MAX_ID_LENGTH, "interface", INTERFACE_EXAMPLE); + + res->href = OICStrdup(href); + res->types = rt.array; + res->typeLen = rt.length; + res->interfaces = _if.array; + res->interfaceLen = _if.length; + } + } + + result = OCCloudAclIndividualUpdateAce(NULL, aclid, aces, endPoint, callback); +exit: + if (aces) + { + for (int k = 0; k < i; k++) + { + cloudAce_t *ace = &aces[k]; + OICFree(ace->aceId); + + if (ace->resources) + { + for (int l = 0; l < j; l++) + { + OicSecRsrc_t *res = &ace->resources[l]; + OICFree(res->href); + + stringArray_t rt = {.array = res->types, .length = res->typeLen}; + clearStringArray(&rt); + + stringArray_t _if = {.array = res->interfaces, .length = res->interfaceLen}; + clearStringArray(&_if); + } + } + + } + } + return result; +} + +OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char aclid[MAX_ID_LENGTH] = { 0 }; + + readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE); + + return OCCloudAclIndividualDelete(NULL, aclid, endPoint, callback); +} + +OCStackResult OCWrapperAclCreateGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char gtype[16] = { 0 }; + char gmid[MAX_ID_LENGTH] = { 0 }; + + readString(gtype, sizeof(gtype), "Group type value", "Public"); + readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2); + + return OCCloudAclCreateGroup(NULL, gtype, OPTIONAL(gmid), endPoint, callback); +} + +OCStackResult OCWrapperAclFindMyGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char mid[MAX_ID_LENGTH] = { 0 }; + + readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2); + + return OCCloudAclFindMyGroup(NULL, OPTIONAL(mid), endPoint, callback); +} + +OCStackResult OCWrapperAclDeleteGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char gid[MAX_ID_LENGTH] = { 0 }; + char gmid[MAX_ID_LENGTH] = { 0 }; + + readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1); + + readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2); + + return OCCloudAclDeleteGroup(NULL, gid, OPTIONAL(gmid), endPoint, callback); +} + +OCStackResult OCWrapperAclJoinToInvitedGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char gid[MAX_ID_LENGTH] = { 0 }; + + readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1); + + return OCCloudAclJoinToInvitedGroup(NULL, gid, endPoint, callback); +} + +OCStackResult OCWrapperAclObserveGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char gid[MAX_ID_LENGTH] = { 0 }; + + readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1); + + return OCCloudAclObserveGroup(NULL, gid, endPoint, callback); +} + +OCStackResult OCWrapperAclShareDeviceIntoGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + OCStackResult result = OC_STACK_NO_MEMORY; + char gid[MAX_ID_LENGTH] = { 0 }; + stringArray_t midlist = {0,0}; + stringArray_t dilist = {0,0}; + + readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1); + + readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2); + + readStringArray(&dilist, MAX_ID_LENGTH, "device list", UUID_EXAMPLE_1); + + result = OCCloudAclShareDeviceIntoGroup(NULL, gid, &midlist, &dilist, endPoint, callback); + + clearStringArray(&midlist); + clearStringArray(&dilist); + + return result; +} + +OCStackResult OCWrapperAclDeleteDeviceFromGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + OCStackResult result = OC_STACK_NO_MEMORY; + char gid[MAX_ID_LENGTH] = { 0 }; + stringArray_t midlist = {0,0}; + stringArray_t dilist = {0,0}; + + readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1); + + readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2); + + readStringArray(&dilist, MAX_ID_LENGTH, "device list", UUID_EXAMPLE_1); + + result = OCCloudAclDeleteDeviceFromGroup(NULL, gid, &midlist, &dilist, endPoint, callback); + + clearStringArray(&midlist); + clearStringArray(&dilist); + + return result; +} + +OCStackResult OCWrapperAclGroupGetInfo(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char gid[MAX_ID_LENGTH] = { 0 }; + char mid[MAX_ID_LENGTH] = { 0 }; + + readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1); + + readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2); + + return OCCloudAclGroupGetInfo(NULL, gid, OPTIONAL(mid), endPoint, callback); +} + +OCStackResult OCWrapperAclInviteUser(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + OCStackResult result = OC_STACK_NO_MEMORY; + char uid[MAX_ID_LENGTH] = { 0 }; + stringArray_t midlist = {0,0}; + stringArray_t gidlist = {0,0}; + + readOptionalString(uid, sizeof(uid), "user id value", UUID_EXAMPLE_2); + + readStringArray(&gidlist, MAX_ID_LENGTH, "group id list", UUID_EXAMPLE_1); + + readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2); + + result = OCCloudAclInviteUser(NULL, OPTIONAL(uid), &gidlist, &midlist, endPoint, callback); + + clearStringArray(&midlist); + clearStringArray(&gidlist); + + return result; +} + +OCStackResult OCWrapperAclGetInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char uid[MAX_ID_LENGTH] = { 0 }; + + readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2); + + return OCCloudAclGetInvitation(NULL, OPTIONAL(uid), endPoint, callback); +} + +OCStackResult OCWrapperAclDeleteInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char uid[MAX_ID_LENGTH] = { 0 }; + char gid[MAX_ID_LENGTH] = { 0 }; + + readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2); + readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1); + + return OCCloudAclDeleteInvitation(NULL, OPTIONAL(uid), gid, endPoint, callback); +} + +OCStackResult OCWrapperAclCancelInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char uid[MAX_ID_LENGTH] = { 0 }; + char gid[MAX_ID_LENGTH] = { 0 }; + char mid[MAX_ID_LENGTH] = { 0 }; + + readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2); + + readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1); + readString(mid, sizeof(mid), "member id value", ID_EXAMPLE_1); + + return OCCloudAclCancelInvitation(NULL, OPTIONAL(uid), gid, mid, endPoint, callback); +} + +OCStackResult OCWrapperAclPolicyCheck(const OCDevAddr *endPoint, OCCloudResponseCB callback) +{ + char sid[MAX_ID_LENGTH] = { 0 }; + char di[MAX_ID_LENGTH] = { 0 }; + char rm[16] = { 0 }; + char user_uri[32] = { 0 }; + + readString(sid, sizeof(sid), "subject id", UUID_EXAMPLE_1); + readString(di, sizeof(di), "device id", UUID_EXAMPLE_2); + readString(rm, sizeof(rm), "request method", "GET or POST or DELETE"); + readString(user_uri, sizeof(user_uri), "request uri", RESOURCE_URI_EXAMPLE); + + return OCCloudAclPolicyCheck(NULL, sid, di, rm, user_uri, endPoint, callback); +} diff --git a/resource/provisioning/examples/cloudWrapper.h b/resource/provisioning/examples/cloudWrapper.h new file mode 100644 index 0000000..51e5538 --- /dev/null +++ b/resource/provisioning/examples/cloudWrapper.h @@ -0,0 +1,245 @@ +/* ***************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * *****************************************************************/ +#ifndef OC_CLOUD_WRAPPER_H +#define OC_CLOUD_WRAPPER_H + +#include "occloudprovisioning.h" +#include "OCCloudProvisioning.h" + +using namespace OC; +/** + * Certificate-Issue request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperCertificateIssueRequest(OCCloudProvisioning& ptr, ResponseCallBack callback); + +/** + * CRL GET request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result +*/ +OCStackResult OCWrapperGetCRL(OCCloudProvisioning& ptr, ResponseCallBack callback); + +/** + * CRL POST request function (with Serial Numbers list to revoke) + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperPostCRL(OCCloudProvisioning& ptr, ResponseCallBack callback); + +/** + * ACL id retrieve by device id + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclIdGetByDevice(OCCloudProvisioning& ptr, AclIdResponseCallBack callback); + +/** + * ACL id create + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclIdCreate(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL id delete + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclIdDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL individual get info + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclIndividualGetInfo(OCCloudProvisioning& ptr, ResponseCallBack callback); + +/** + * ACL individual update ACE + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL individual delete + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL post group request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclCreateGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL get group request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclFindMyGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL delete group request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclDeleteGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL join to invited group request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclJoinToInvitedGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL observe group request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclObserveGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL share device into group request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclShareDeviceIntoGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL delete device from group request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclDeleteDeviceFromGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL get group info request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclGroupGetInfo(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL invite user to group request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclInviteUser(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL get invitation request function + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclGetInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL delete invitation request function (by receiver) + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclDeleteInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL cancel invitation request function (by sender) + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclCancelInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * ACL check that given request can be applied to resource + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ +OCStackResult OCWrapperAclPolicyCheck(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** + * Read user input (expect string value) + * + * @param[out] item string item to fill + * @param[in] length max allowed string length + * @param[in] description item description + * @param[in] example item example + */ +void readString(char* item, int length, const char* description, const char* example); + +/** + * Read user input (expect integer value) + * + * @param[out] item integer item to fill + * @param[in] description item description + * @param[in] example item example + */ +void readInteger(int* item, const char* description, const char* example); + + +#endif //OC_CLOUD_WRAPPER_H diff --git a/resource/provisioning/examples/provisioningclient.cpp b/resource/provisioning/examples/provisioningclient.cpp index ec57563..b5b43d2 100644 --- a/resource/provisioning/examples/provisioningclient.cpp +++ b/resource/provisioning/examples/provisioningclient.cpp @@ -39,7 +39,7 @@ #include "aclresource.h" #include "utlist.h" -#define MAX_URI_LENGTH (64) +//#define MAX_URI_LENGTH (64) #define MAX_PERMISSION_LENGTH (5) #define ACL_RESRC_ARRAY_SIZE (3) #define CREATE (1) diff --git a/resource/provisioning/examples/rootca.crt b/resource/provisioning/examples/rootca.crt new file mode 100644 index 0000000..54ec780 --- /dev/null +++ b/resource/provisioning/examples/rootca.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/jCCAeYCAQEwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDAeFw0xNjA2MjgwNTMzNThaFw0yNjA2MjYwNTMzNThaMEUxCzAJBgNVBAYTAkFV +MRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRz +IFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1HHkfMG9c +BJ7ZeCIBKe7pSjpptvi+hzpdV72W7szpWDlTQdUaRxKL9aoNxbyuF5OL8xAQ9s28 +IqIxdPW7X3JAmkLigzMCo2xtXHz/OyvomU6fhibneQw5De+iUoD68zdG+/k1NcAW +xx+VEAMw4fvZvYSVEQ1aKFnjtrQ8o6Zfe5+MRTvBq+G0+jwZWJEoKbpxIPpNWPGx +AV17tEpe+lg27jEYDYG1QUiL2TG80ZjQQL95OjETYf8EIxoqrKHvHCvDin0zdd+E +qPN0Y+Rhkl3PYoxWm7d8z0p1mD7lcwOMvy1KgEgtJ7SHy0D2SIW/KaDox/kRPC1P +ksFeAS2B0Z9zAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAtHjimMywXn893Ifu1v +tNnL9ITMpQhsHAlg1QBVEyjGZLIjUgMhsWljVwTC1PdBrO7V0ElYbeV+LKYGwDk6 +fjBJogCLgZiUw18F8TjHC/qDsoWEsm1iB4KcTZkk0nm/2vidHK0TMLzCohR71/vN +KS2rtiQDYGKe9EzjNSO3GlCWkVTYtJNhALa/BfDza5keRkwmldJYhlx4rQH5yVRn +t5k87vjX0h7m8MzIwiAb2s/b9XBlM1FuFx3FxcVjBl7KtUAU7twU8v5LenjWDSH1 +D1jnKiZUUspgovhosPRqmxGNXldaX1E+RJmxdtqUVg4co/zjAbTY7C+7ZYIZBo46 +Ll0= +-----END CERTIFICATE----- diff --git a/resource/provisioning/src/OCCloudProvisioning.cpp b/resource/provisioning/src/OCCloudProvisioning.cpp new file mode 100644 index 0000000..29b7ee8 --- /dev/null +++ b/resource/provisioning/src/OCCloudProvisioning.cpp @@ -0,0 +1,211 @@ +/* ***************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * *****************************************************************/ + +#include "ocstack.h" +#include "OCCloudProvisioning.h" + +namespace OC +{ + void OCCloudProvisioning::callbackWrapper(void *ctx, + OCStackResult result, + void *data) + { + CloudProvisionContext* context = static_cast(ctx); + + std::thread exec(context->callback, result, data); + exec.detach(); + + delete context; + } + + void OCCloudProvisioning::aclIdResponseWrapper(void *ctx, + OCStackResult result, + void *data) + { + std::string aclId = ""; + AclIdContext* context = static_cast(ctx); + + if ((OC_STACK_OK == result) && data) + { + aclId = (char *)data; + } + std::thread exec(context->callback, result, aclId); + exec.detach(); + + delete context; + } + + OCCloudProvisioning::OCCloudProvisioning(std::string& ipAddr, uint16_t port) + { + memset(&m_devAddr, 0, sizeof(m_devAddr)); + memcpy(m_devAddr.addr, ipAddr.c_str(), MAX_ADDR_STR_SIZE); + m_devAddr.port = port; + m_csdkLock = OCPlatform_impl::Instance().csdkLock(); + } + + OCCloudProvisioning::~OCCloudProvisioning(void) + { + } + + OCStackResult OCCloudProvisioning::requestCertificate(ResponseCallBack callback) + { + if (!callback) + { + oclog() <<"Result callback can't be null"; + return OC_STACK_INVALID_CALLBACK; + } + + OCStackResult result; + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + CloudProvisionContext *context = new CloudProvisionContext(callback); + + std::lock_guard lock(*cLock); + result = OCCloudCertificateIssueRequest(static_cast(context), &m_devAddr, + &OCCloudProvisioning::callbackWrapper); + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + return result; + } + + OCStackResult OCCloudProvisioning::getIndividualAclInfo(const std::string& aclId, + ResponseCallBack callback) + { + if (!callback) + { + oclog() <<"Result callback can't be null"; + return OC_STACK_INVALID_CALLBACK; + } + + OCStackResult result; + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + CloudProvisionContext *context = new CloudProvisionContext(callback); + + std::lock_guard lock(*cLock); + result = OCCloudAclIndividualGetInfo(static_cast(context), aclId.c_str(), + &m_devAddr, + &OCCloudProvisioning::callbackWrapper); + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + return result; + } + + OCStackResult OCCloudProvisioning::getAclIdByDevice(const std::string& deviceId, + AclIdResponseCallBack callback) + { + if (!callback) + { + oclog() <<"Result callback can't be null"; + return OC_STACK_INVALID_CALLBACK; + } + + OCStackResult result; + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + AclIdContext *context = new AclIdContext(callback); + + std::lock_guard lock(*cLock); + result = OCCloudAclIdGetByDevice(static_cast(context), deviceId.c_str(), + &m_devAddr, + &OCCloudProvisioning::aclIdResponseWrapper); + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + return result; + } + + OCStackResult OCCloudProvisioning::getCRL(ResponseCallBack callback) + { + if (!callback) + { + oclog() <<"Result callback can't be null"; + return OC_STACK_INVALID_CALLBACK; + } + + OCStackResult result; + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + CloudProvisionContext *context = new CloudProvisionContext(callback); + + std::lock_guard lock(*cLock); + result = OCCloudGetCRL(static_cast(context), &m_devAddr, + &OCCloudProvisioning::callbackWrapper); + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + return result; + } + + OCStackResult OCCloudProvisioning::postCRL(const std::string& thisUpdate, + const std::string& nextUpdate, + const OCByteString *crl, + const stringArray_t *serialNumbers, + ResponseCallBack callback) + { + if (!callback) + { + oclog() <<"Result callback can't be null"; + return OC_STACK_INVALID_CALLBACK; + } + + OCStackResult result; + auto cLock = m_csdkLock.lock(); + + if (cLock) + { + CloudProvisionContext *context = new CloudProvisionContext(callback); + + std::lock_guard lock(*cLock); + result = OCCloudPostCRL(static_cast(context), thisUpdate.c_str(), + nextUpdate.c_str(), crl, serialNumbers, &m_devAddr, + &OCCloudProvisioning::callbackWrapper); + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + return result; + } + +} diff --git a/resource/provisioning/unittests/OCCloudProvisioningTest.cpp b/resource/provisioning/unittests/OCCloudProvisioningTest.cpp new file mode 100755 index 0000000..304369a --- /dev/null +++ b/resource/provisioning/unittests/OCCloudProvisioningTest.cpp @@ -0,0 +1,81 @@ +/* ***************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * *****************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TIMEOUT 5 +static std::string IP("127.0.0.1"); +static uint16_t PORT = 5683; + +namespace OCCloudProvisioningTest +{ + using namespace OC; + + void resultCallback(OCStackResult result, void *data) + { + (void)result; + (void)data; + } + + TEST(RequestCertTest, TestNullCallback) + { + OCCloudProvisioning cloud(IP, PORT); + EXPECT_EQ(OC_STACK_INVALID_CALLBACK, cloud.requestCertificate(NULL)); + } + + TEST(AclIdByDeviceTest, AclIdNullCallback) + { + OCCloudProvisioning cloud(IP, PORT); + std::string devId(""); + EXPECT_EQ(OC_STACK_INVALID_CALLBACK, cloud.getAclIdByDevice(devId, NULL)); + } + + TEST(AclInfoTest, AclInfoNullCallback) + { + OCCloudProvisioning cloud(IP, PORT); + std::string aclId(""); + EXPECT_EQ(OC_STACK_INVALID_CALLBACK, cloud.getIndividualAclInfo(aclId, NULL)); + } + + TEST(GetCRLTest, GetCrlNullCallback) + { + OCCloudProvisioning cloud(IP, PORT); + EXPECT_EQ(OC_STACK_INVALID_CALLBACK, cloud.getCRL(NULL)); + } + + TEST(PostCRLTest, PostCrlNullCallback) + { + std::string thisUpdate(""); + std::string nextUpdate(""); + OCByteString crl; + stringArray_t serials; + OCCloudProvisioning cloud(IP, PORT); + EXPECT_EQ(OC_STACK_INVALID_CALLBACK, cloud.postCRL(thisUpdate, + nextUpdate, + &crl, &serials, NULL)); + } +} diff --git a/resource/provisioning/unittests/SConscript b/resource/provisioning/unittests/SConscript index e40ca11..b87779e 100755 --- a/resource/provisioning/unittests/SConscript +++ b/resource/provisioning/unittests/SConscript @@ -40,6 +40,7 @@ provisiontests_env.PrependUnique(CPPPATH = [ '../../csdk/security/provisioning/include', '../../csdk/security/provisioning/include/oxm', '../../csdk/security/provisioning/include/internal', + '../../csdk/security/provisioning/include/cloud', '../../csdk/stack/include/internal', '../../csdk/connectivity/api', '../../csdk/connectivity/inc/pkix', @@ -88,7 +89,16 @@ if provisiontests_env.get('LOGGING'): ###################################################################### # Source files and Targets ###################################################################### -unittests = provisiontests_env.Program('provisiontests', ['OCProvisioningTest.cpp']) +ocprovisiontest_src = [ + 'OCProvisioningTest.cpp' + ] + +if provisiontests_env.get('WITH_TCP') == True: + ocprovisiontest_src = ocprovisiontest_src + [ + 'OCCloudProvisioningTest.cpp' + ] + +unittests = provisiontests_env.Program('provisiontests', ocprovisiontest_src) Alias("provisiontests", [unittests]) diff --git a/service/easy-setup/mediator/richsdk/SConscript b/service/easy-setup/mediator/richsdk/SConscript index 41a73fa..60c1c00 100644 --- a/service/easy-setup/mediator/richsdk/SConscript +++ b/service/easy-setup/mediator/richsdk/SConscript @@ -109,7 +109,8 @@ if target_os in ['android','linux']: env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include', env.get('SRC_DIR') + '/resource/csdk/security/include/internal', env.get('SRC_DIR') + '/resource/csdk/connectivity/api/', - env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal', + env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal', + env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/cloud', env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/oxm']) if env.get('WITH_TCP') == True: easy_setup_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto']) diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript index 99021b9..9b17f05 100644 --- a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript @@ -50,6 +50,7 @@ mediator_env.PrependUnique(CPPPATH = [ env.get('SRC_DIR') + '/resource/csdk/stack/include', env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include', env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal', + env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/cloud', env.get('SRC_DIR') + '/resource/csdk/logger/include', env.get('SRC_DIR') + '/resource/csdk/security/include', env.get('SRC_DIR') + '/resource/csdk/connectivity/api', -- 2.7.4