'../../oc_logger/include',
'../connectivity/lib/libcoap-4.1.1',
'../connectivity/external/inc',
+ '../connectivity/common/inc',
'../connectivity/inc',
'../connectivity/api',
'../security/include',
- '../security/include/internal',
+ '../security/include/internal'
])
if target_os not in ['arduino', 'windows', 'winrt']:
OCSRM_SRC + 'resourcemanager.c',
OCSRM_SRC + 'aclresource.c',
OCSRM_SRC + 'amaclresource.c',
+ OCSRM_SRC + 'amsmgr.c',
OCSRM_SRC + 'pstatresource.c',
OCSRM_SRC + 'doxmresource.c',
OCSRM_SRC + 'credresource.c',
OCSRM_SRC + 'resourcemanager.c',
OCSRM_SRC + 'aclresource.c',
OCSRM_SRC + 'amaclresource.c',
+ OCSRM_SRC + 'amsmgr.c',
OCSRM_SRC + 'pstatresource.c',
OCSRM_SRC + 'doxmresource.c',
OCSRM_SRC + 'credresource.c',
*/
char* BinToAclJSON(const OicSecAcl_t * acl);
+
/**
* This function deletes ACL data.
*
*/
void DeleteACLList(OicSecAcl_t* acl);
+
+/**
+ * This function installs a new ACL.
+ * @param newJsonStr JSON string representing a new ACL.
+ *
+ * @retval OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InstallNewACL(const char* newJsonStr);
+
+
#ifdef __cplusplus
}
#endif
void DeInitAmaclResource();
/**
- * This method is used by PolicyEngine to retrieve Amacl for a Subject.
+ * This method is used by PolicyEngine to retrieve amsId for the resource.
+ * If the Amacl is found for the given resource then populate the parameter
+ * amsId with Amacl resource amss id.
*
- * @param subjectId ID of the subject for which Amacl is required.
- * @param savePtr is used internally by @ref GetAmaclResourceData to maintain index between
- * successive calls for same subjectId.
+ * @param resource resource for which AMS service is required.
+ * @param amsId ID of the ams service for the given resource
*
- * @retval reference to @ref OicSecAmacl_t if Amacl is found, else NULL
+ * @retval
+ * OC_STACK_OK If Amacl found for the resource
+ * OC_STACK_ERROR If no Amacl found for the resource
*
- * @note On the first call to @ref GetAmaclResourceData, savePtr should point to NULL
*/
-const OicSecAmacl_t* GetAmaclResourceData(const OicUuid_t* subjectId, OicSecAmacl_t **savePtr);
+OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsId);
/**
* This function converts Amacl data into JSON format.
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH 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 IOTVT_SRM_AMSMGR_H
+#define IOTVT_SRM_AMSMGR_H
+
+#include "ocstack.h"
+#include "logger.h"
+#include "policyengine.h"
+#include "securevirtualresourcetypes.h"
+#include "cainterface.h"
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct PEContext PEContext_t;
+/**
+ * @brief The AMS context..
+ */
+typedef struct AmsMgrContext
+{
+ OicUuid_t amsDeviceId; /**< DeviceID of the oic.sec.ams service. */
+ CAEndpoint_t *endpoint;
+ CARequestInfo_t *requestInfo;
+} AmsMgrContext_t;
+
+
+/**
+ * @brief This method updates AmsMgr context's endpoint & requestInfo
+ *
+ * @param context Policy engine context.
+ * @param endpoint CA Endpoint info of the requester
+ * @param requestInfo CA RequestInfo of the requester
+ */
+OCStackResult UpdateAmsMgrContext(PEContext_t *context, const CAEndpoint_t *endpoint,
+ const CARequestInfo_t *requestInfo);
+
+/**
+ *
+ * This method is called by PolicyEngine to Discover AMS service.
+ * It sends muticast discovery request such as
+ * /oic/sec/doxm?deviceid="AMSSrvcDeviceID" to discover AMS service
+ * with deviceId="AMSSrvcDeviceID"
+ *
+ * @param context Policy engine context.
+ *
+ * @retval
+ * OC_STACK_OK If able to successfully send multicast discovery request.
+ * OC_STACK_ERROR If unable to successfully send multicast discovery request due to error.
+ *
+ */
+OCStackResult DiscoverAmsService(PEContext_t *context);
+
+
+/**
+ *
+ * This method sends unicast request to retrieve the secured port info of the
+ * discovered AMS service. It sends unicast discovery request such as
+ * /oic/res?rt="oic.sec.doxm" to the discovered AMS service
+ *
+ * @param context Policy engine context.
+ *
+ * @retval
+ * OC_STACK_OK If able to successfully send unicast discovery request
+ * OC_STACK_ERROR If unable to successfully send unicast discovery request due to error
+ *
+ */
+OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,OCDevAddr *devAddr,
+ OCConnectivityType connType);
+
+
+/**
+ *
+ * This method sends unicast request to AMS service to get ACL for
+ * the Subject and/or Resource. It sends unicast request such as
+ * /oic/sec/acl?sub="subjectId";rsrc="/a/led" to get the ACL for
+ * the subject & resource
+ *
+ * @param context Policy engine context.
+ *
+ * @retval
+ * OC_STACK_OK If able to successfully send unicast ACL request
+ * OC_STACK_ERROR If unable to successfully send unicast ACL request due to error
+ *
+ */
+OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType,
+ uint16_t securedPort);
+
+
+/*
+ * Cleanup CARequestInfo_t object
+ * @param requestInfo pointer to RequestInfo_t object
+ */
+void FreeCARequestInfo(CARequestInfo_t *requestInfo);
+
+
+/*
+ * This method is used by Policy engine to checks Amacl resource.
+ * If Amacl is found then it fills up context->amsMgrContext->amsDeviceId
+ * with amsID of the Amacl else leaves it empty.
+ *
+ * @param context Policy engine context.
+ *
+ * @return true if AMacl for the resource is found
+ * false if AMacl for the resource is not found
+ */
+bool FoundAmaclForRequest(PEContext_t *context);
+
+
+/*
+ * This method is used by Policy engine to process AMS request
+ * *
+ * @param context Policy engine context.
+ *
+ * @return None
+ */
+void ProcessAMSRequest(PEContext_t *context);
+
+#endif //IOTVT_SRM_AMSMGR_H
#include "logger.h"
#include "securevirtualresourcetypes.h"
#include "cainterface.h"
+#include "amsmgr.h"
#include <stdlib.h>
#include <stdint.h>
+typedef struct AmsMgrContext AmsMgrContext_t;
+
typedef enum PEState
{
- STOPPED = 0,
- AWAITING_REQUEST,
- BUSY
+ STOPPED = 0, //Policy engine state machine is not running
+ AWAITING_REQUEST, //Can process new request
+ AWAITING_AMS_RESPONSE, //Can't process new request; waiting for AMS response
+ BUSY //Can't process new request as processing other requests
} PEState_t;
+
typedef struct PEContext
{
PEState_t state;
- OicUuid_t *subject;
- char *resource;
+ OicUuid_t subject;
+ char resource[MAX_URI_LENGTH];
uint16_t permission;
bool matchingAclFound;
+ bool amsProcessing;
SRMAccessResponse_t retVal;
+ AmsMgrContext_t *amsMgrContext;
} PEContext_t;
/**
*/
uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method);
+
+/*
+ * This method reset Policy Engine context to default state and update
+ * it's state to @param state.
+ *
+ * @param context Policy engine context.
+ * @param state Set Policy engine state to this.
+ *
+ * @return none
+ */
+void SetPolicyEngineState(PEContext_t *context, const PEState_t state);
+
#endif //IOTVT_SRM_PE_H
#ifndef SECURITYRESOURCEMANAGER_H_
#define SECURITYRESOURCEMANAGER_H_
+#include "securevirtualresourcetypes.h"
+
#ifdef __cplusplus
extern "C" {
#endif
*/
void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler);
+
+/**
+ * @brief Sends Response
+ * @param resposeVal SRMAccessResponse_t value
+
+ * @return NONE
+ */
+void SRMSendResponse(SRMAccessResponse_t responseVal);
+
#ifdef __cplusplus
}
#endif
#define RESOURCE_NOT_FOUND_DEF (1 << 4)
#define POLICY_ENGINE_ERROR_DEF (1 << 5)
#define INVALID_PERIOD_DEF (1 << 6)
+#define ACCESS_WAITING_DEF (1 << 7)
+#define AMS_SERVICE_DEF (1 << 8)
#define REASON_MASK_DEF (INSUFFICIENT_PERMISSION_DEF | \
INVALID_PERIOD_DEF | \
SUBJECT_NOT_FOUND_DEF | \
| RESOURCE_NOT_FOUND_DEF,
ACCESS_DENIED_POLICY_ENGINE_ERROR = ACCESS_DENIED_DEF
| POLICY_ENGINE_ERROR_DEF,
+ ACCESS_WAITING_FOR_AMS = ACCESS_WAITING_DEF
+ | AMS_SERVICE_DEF,
+ ACCESS_DENIED_AMS_SERVICE_ERROR = ACCESS_DENIED
+ | AMS_SERVICE_DEF
} SRMAccessResponse_t;
/**
}
return false;
}
+
/*
* This method removes ACE for the subject and resource from the ACL
*
ParseQueryIterInit((unsigned char *)query, &parseIter);
+
while(GetNextQuery(&parseIter))
{
if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME, parseIter.attrLen) == 0)
*savePtr = NULL;
return NULL;
}
+
+
+OCStackResult InstallNewACL(const char* newJsonStr)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ // Convert JSON ACL data into binary. This will also validate the ACL data received.
+ OicSecAcl_t* newAcl = JSONToAclBin(newJsonStr);
+
+ if (newAcl)
+ {
+ // Append the new ACL to existing ACL
+ LL_APPEND(gAcl, newAcl);
+
+ // Convert ACL data into JSON for update to persistent storage
+ char *jsonStr = BinToAclJSON(gAcl);
+ if (jsonStr)
+ {
+ cJSON *jsonAcl = cJSON_Parse(jsonStr);
+ OICFree(jsonStr);
+
+ if (jsonAcl)
+ {
+ ret = UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl);
+ }
+ cJSON_Delete(jsonAcl);
+ }
+ }
+
+ return ret;
+}
DeleteAmaclList(gAmacl);
gAmacl = NULL;
}
+
+
+OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsDeviceId)
+{
+ OicSecAmacl_t *amacl = NULL;
+
+ VERIFY_NON_NULL(TAG, resource, ERROR);
+ VERIFY_NON_NULL(TAG, amsDeviceId, ERROR);
+
+ LL_FOREACH(gAmacl, amacl)
+ {
+ for(size_t i = 0; i < amacl->resourcesLen; i++)
+ {
+ if (strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])) == 0)
+ {
+ //Returning the ID of the first AMS service for the resource
+ memcpy(amsDeviceId, &amacl->amss[0], sizeof(*amsDeviceId));
+ return OC_STACK_OK;
+ }
+ }
+ }
+
+exit:
+ return OC_STACK_ERROR;
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH 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 "oic_malloc.h"
+#include "amsmgr.h"
+#include "resourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "logger.h"
+#include "ocrandom.h"
+#include "aclresource.h"
+#include "amaclresource.h"
+#include "srmutility.h"
+#include "base64.h"
+#include "secureresourcemanager.h"
+#include "doxmresource.h"
+#include "policyengine.h"
+#include "oic_string.h"
+#include "caremotehandler.h"
+#include <string.h>
+
+#define TAG "SRM-AMSMGR"
+
+
+ //Callback for AMS service multicast discovery request.
+static OCStackApplicationResult AmsMgrDiscoveryCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse);
+
+//Callback for unicast secured port discovery request.
+static OCStackApplicationResult SecurePortDiscoveryCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse);
+
+//Callback for unicast ACL request
+static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse);
+
+
+OCStackResult DiscoverAmsService(PEContext_t *context)
+{
+ OC_LOG(INFO, TAG, "IN DiscoverAmsService");
+
+ OCStackResult ret = OC_STACK_ERROR;
+ const char DOXM_DEVICEID_QUERY_FMT[] = "%s?%s=%s";
+ char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {};
+ OCCallbackData cbData = {.context=NULL};
+ char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
+ uint32_t outLen = 0;
+ B64Result b64Ret;
+
+ VERIFY_NON_NULL(TAG, context, ERROR);
+ b64Ret = b64Encode(context->amsMgrContext->amsDeviceId.id,
+ sizeof(context->amsMgrContext->amsDeviceId.id), base64Buff, sizeof(base64Buff), &outLen);
+ VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
+ snprintf(uri, sizeof(uri), DOXM_DEVICEID_QUERY_FMT, OIC_RSRC_DOXM_URI,
+ OIC_JSON_DEVICE_ID_NAME, base64Buff);
+
+ cbData.cb = &AmsMgrDiscoveryCallback;
+ cbData.context = (void*)context;
+
+ /* TODO
+ * If no good response was received for this discovery request,
+ * PE would be blocked forever waiting for AMS service to respond with the ACE.
+ * Need logic to reset the PE state and send ACCESS_DENIED response,
+ * when discovery response from AMS service is not received within certain time.
+ */
+ OC_LOG_V(INFO, TAG,"AMS Manager Sending Multicast Discovery with URI = %s", uri);
+ ret = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL,
+ CT_DEFAULT, OC_LOW_QOS, &cbData, NULL, 0);
+
+exit:
+ OC_LOG(INFO, TAG, "Leaving DiscoverAmsService");
+ return ret;
+}
+
+
+static OCStackApplicationResult AmsMgrDiscoveryCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ OC_LOG_V(INFO, TAG, "%s Begin", __func__ );
+
+ if (!ctx ||
+ !clientResponse ||
+ !clientResponse->payload||
+ (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)||
+ (OC_STACK_OK != clientResponse->result))
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid Response ", __func__);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ (void)handle;
+ PEContext_t *context = (PEContext_t *) ctx;
+ if (context->state != AWAITING_AMS_RESPONSE)
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid PE State ", __func__);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ OicSecDoxm_t *doxm = NULL;
+ OC_LOG_V(INFO, TAG, "Doxm DeviceId Discovery response = %s\n",
+ ((OCSecurityPayload*)clientResponse->payload)->securityData);
+ doxm = JSONToDoxmBin(((OCSecurityPayload*)clientResponse->payload)->securityData);
+
+ //As doxm is NULL amsmgr can't test if response from trusted AMS service
+ //so keep the transaction.
+ if(NULL == doxm)
+ {
+ OC_LOG_V(ERROR, TAG, "%s : Unable to convert JSON to Binary",__func__);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ OicUuid_t deviceId = {.id={}};
+ memcpy(&deviceId, &doxm->deviceID, sizeof(deviceId));
+ OICFree(doxm);
+
+ /* TODO : By assuming that the first response received is the actual
+ * AMS service, a 'bad device' can cause DoS attack.
+ */
+ if (memcmp(&context->amsMgrContext->amsDeviceId, &deviceId,
+ sizeof(context->amsMgrContext->amsDeviceId)) == 0)
+ {
+ OC_LOG(INFO, TAG, "AMS Manager Sending unicast discovery to get secured port info");
+ //Sending Unicast discovery to get secure port information
+ if(OC_STACK_OK == SendUnicastSecurePortDiscovery(context, &clientResponse->devAddr,
+ clientResponse->connType))
+ {
+ context->retVal = ACCESS_WAITING_FOR_AMS;
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,OCDevAddr *devAddr,
+ OCConnectivityType connType)
+{
+ OC_LOG(INFO, TAG, "IN SendUnicastSecurePortDiscovery");
+
+ const char RES_DOXM_QUERY_FMT[] = "%s?%s=%s";
+ OCCallbackData cbData = {.context=NULL};
+ char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {};
+ snprintf(uri, sizeof(uri), RES_DOXM_QUERY_FMT, OC_RSRVD_WELL_KNOWN_URI,
+ OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM);
+
+ cbData.cb = &SecurePortDiscoveryCallback;
+ cbData.context = context;
+
+ OC_LOG_V(INFO, TAG, "AMS Manager Sending Unicast Discovery with URI = %s", uri);
+
+ return OCDoResource(NULL, OC_REST_DISCOVER, uri, devAddr, NULL,
+ connType, OC_LOW_QOS, &cbData, NULL, 0);
+}
+
+static OCStackApplicationResult SecurePortDiscoveryCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ OC_LOG(INFO, TAG, "In SecurePortDiscoveryCallback");
+
+ if (!ctx ||
+ !clientResponse ||
+ !clientResponse->payload||
+ (PAYLOAD_TYPE_DISCOVERY != clientResponse->payload->type)||
+ (OC_STACK_OK != clientResponse->result))
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid Response ", __func__);
+ SRMSendResponse(ACCESS_DENIED_AMS_SERVICE_ERROR);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ PEContext_t *context = (PEContext_t *) ctx;
+ (void)handle;
+ if (context->state != AWAITING_AMS_RESPONSE)
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid PE State ", __func__);
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ OCResourcePayload* resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
+
+ //Verifying if the ID of the sender is an AMS service that this device trusts.
+ if(memcmp(context->amsMgrContext->amsDeviceId.id, resPayload->sid,
+ sizeof(context->amsMgrContext->amsDeviceId.id)) != 0)
+ {
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ if (resPayload && resPayload->secure)
+ {
+ if(OC_STACK_OK == SendAclReq(context, &clientResponse->devAddr, clientResponse->connType,
+ resPayload->port))
+ {
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ OC_LOG(INFO, TAG, "Can not find secure port information");
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType,
+ uint16_t securedPort)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ const char GET_ACE_QUERY_FMT[] = "%s?%s=%s;%s=%s";
+ char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
+ uint32_t outLen = 0;
+ char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {};
+ OCCallbackData cbData = {.context=NULL};
+ OCDevAddr destAddr = {.adapter = OC_ADAPTER_IP};
+ B64Result b64Ret;
+
+ VERIFY_NON_NULL(TAG, context, ERROR);
+ VERIFY_NON_NULL(TAG, devAddr, ERROR);
+
+ b64Ret = b64Encode(context->subject.id, sizeof(context->subject.id),
+ base64Buff, sizeof(base64Buff), &outLen);
+ VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
+
+ snprintf(uri, sizeof(uri), GET_ACE_QUERY_FMT, OIC_RSRC_ACL_URI,
+ OIC_JSON_SUBJECT_NAME, base64Buff,
+ OIC_JSON_RESOURCES_NAME, context->resource);
+
+ cbData.cb = &AmsMgrAclReqCallback;
+ cbData.context = context;
+
+ destAddr = *devAddr;
+ //update port info
+ destAddr.flags = (OCTransportFlags)(destAddr.flags | OC_FLAG_SECURE);
+ destAddr.port = securedPort;
+
+ OC_LOG_V(INFO, TAG, "AMS Manager Sending Unicast ACL request with URI = %s", uri);
+ ret = OCDoResource(NULL, OC_REST_GET, uri, &destAddr, NULL,
+ connType, OC_LOW_QOS, &cbData, NULL, 0);
+
+exit:
+ OC_LOG_V(INFO, TAG, "%s returns %d ", __func__, ret);
+ return ret;
+}
+
+
+static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ OC_LOG_V(INFO, TAG, "%s Begin", __func__ );
+
+ (void)handle;
+ PEContext_t *context = (PEContext_t *) ctx;
+ SRMAccessResponse_t rsps;
+
+ if (!ctx ||
+ !clientResponse ||
+ !clientResponse->payload||
+ (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type) ||
+ (clientResponse->result != OC_STACK_OK))
+ {
+ SRMSendResponse(ACCESS_DENIED_AMS_SERVICE_ERROR);
+ goto exit;
+ }
+
+ if (context->state != AWAITING_AMS_RESPONSE)
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid State ", __func__);
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ // Verify before installing ACL if the ID of the sender of this ACL is an AMS
+ //service that this device trusts.
+ rsps = ACCESS_DENIED;
+ if((UUID_LENGTH == clientResponse->identity.id_length) &&
+ memcmp(context->amsMgrContext->amsDeviceId.id, clientResponse->identity.id,
+ sizeof(context->amsMgrContext->amsDeviceId.id)) == 0)
+ {
+ OCStackResult ret =
+ InstallNewACL(((OCSecurityPayload*)clientResponse->payload)->securityData);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ OC_LOG_V(INFO, TAG, "%s : Calling checkPermission", __func__);
+ rsps = CheckPermission(context, &context->subject, context->resource, context->permission);
+ VERIFY_SUCCESS(TAG, (true == IsAccessGranted(rsps)), ERROR);
+
+ OC_LOG_V(INFO, TAG, "%sAccess granted, Calling SRMCallCARequestHandler", __func__);
+ context->retVal = ACCESS_GRANTED;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+exit:
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ FreeCARequestInfo(context->amsMgrContext->requestInfo);
+ OICFree(context->amsMgrContext->endpoint);
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+OCStackResult UpdateAmsMgrContext(PEContext_t *context, const CAEndpoint_t *endpoint,
+ const CARequestInfo_t *requestInfo)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ //The AmsMgr context endpoint and requestInfo will be free from ,
+ //AmsMgrAclReqCallback function
+ if(context->amsMgrContext->endpoint)
+ {
+ OICFree(context->amsMgrContext->endpoint);
+ context->amsMgrContext->endpoint = NULL;
+ }
+ context->amsMgrContext->endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof(CAEndpoint_t ));
+ VERIFY_NON_NULL(TAG, context->amsMgrContext->endpoint, ERROR);
+ *context->amsMgrContext->endpoint = *endpoint;
+
+ if(context->amsMgrContext->requestInfo)
+ {
+ FreeCARequestInfo(context->amsMgrContext->requestInfo);
+ context->amsMgrContext->requestInfo = NULL;
+ }
+ context->amsMgrContext->requestInfo = CACloneRequestInfo(requestInfo);
+ VERIFY_NON_NULL(TAG, context->amsMgrContext->requestInfo, ERROR);
+ ret = OC_STACK_OK;
+exit:
+ return ret;
+}
+
+void FreeCARequestInfo(CARequestInfo_t *requestInfo)
+{
+ OICFree(requestInfo->info.token);
+ OICFree(requestInfo->info.options);
+ OICFree(requestInfo->info.payload);
+ OICFree(requestInfo->info.resourceUri);
+ OICFree(requestInfo);
+}
+
+
+//This method checks for Amacl resource. If Amacl is found then it fills up
+//context->amsMgrContext->amsDeviceId with amsID of the Amacl else leaves it empty.
+bool FoundAmaclForRequest(PEContext_t *context)
+{
+ OC_LOG_V(INFO, TAG, "%s:no ACL found. Searching for AMACL",__func__);
+
+ bool ret = false;
+ VERIFY_NON_NULL(TAG, context, ERROR);
+ memset(&context->amsMgrContext->amsDeviceId, 0, sizeof(context->amsMgrContext->amsDeviceId));
+
+ //Call amacl resource function to get the AMS service deviceID for the resource
+ if(OC_STACK_OK == AmaclGetAmsDeviceId(context->resource, &context->amsMgrContext->amsDeviceId))
+ {
+ OC_LOG_V(INFO, TAG, "%s:AMACL found for the requested resource %s",
+ __func__, context->resource);
+ ret = true;
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "%s:AMACL found for the requested resource %s",
+ __func__, context->resource);
+ ret = false;
+ }
+
+ exit:
+ return ret;
+}
+
+
+void ProcessAMSRequest(PEContext_t *context)
+{
+ OicUuid_t emptyUuid = {.id={}};
+ OC_LOG_V(INFO, TAG, "Entering %s", __func__);
+ if(NULL != context)
+ {
+ if((false == context->matchingAclFound) && (false == context->amsProcessing))
+ {
+ context->amsProcessing = true;
+
+ //Checking if context AMS deviceId is empty
+ if(memcmp(&context->amsMgrContext->amsDeviceId, &emptyUuid, sizeof(OicUuid_t)) != 0 )
+ {
+ if(OC_STACK_OK == DiscoverAmsService(context))
+ {
+ context->retVal = ACCESS_WAITING_FOR_AMS;
+ }
+ else
+ {
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ }
+ }
+ }
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "Leaving %s(context is NULL)", __func__);
+ }
+
+ if(ACCESS_WAITING_FOR_AMS == context->retVal )
+ {
+ OC_LOG_V(INFO, TAG, "Leaving %s(WAITING_FOR_AMS)", __func__);
+ }
+}
#include "oic_malloc.h"
#include "policyengine.h"
+#include "amsmgr.h"
#include "resourcemanager.h"
#include "securevirtualresourcetypes.h"
#include "srmresourcestrings.h"
return true;
}
-
/**
* Set the state and clear other stateful context vars.
*/
void SetPolicyEngineState(PEContext_t *context, const PEState_t state)
{
// Clear stateful context variables.
- OICFree(context->subject);
- context->subject = NULL;
- OICFree(context->resource);
- context->resource = NULL;
+ memset(&context->subject, 0, sizeof(context->subject));
+ memset(&context->resource, 0, sizeof(context->resource));
context->permission = 0x0;
context->matchingAclFound = false;
+ context->amsProcessing = false;
context->retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR;
+ memset(context->amsMgrContext, 0, sizeof(AmsMgrContext_t));
// Set state.
context->state = state;
if(OC_STACK_OK == GetDoxmDevOwnerId(&owner))
{
- retVal = UuidCmp(context->subject, &owner);
+ retVal = UuidCmp(&context->subject, &owner);
}
return retVal;
}
+
+inline static bool IsRequestSubjectEmpty(PEContext_t *context)
+{
+ OicUuid_t emptySubject = {.id={}};
+ return (memcmp(&context->subject, &emptySubject, sizeof(OicUuid_t)) == 0) ?
+ true : false;
+}
+
+
/**
* Bitwise check to see if 'permission' contains 'request'.
* @param permission The allowed CRUDN permission.
{
size_t length = 0;
- // Free any existing subject.
- OICFree(context->subject);
- // Copy the subjectId into context.
- context->subject = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, context->subject, ERROR);
- memcpy(context->subject, subjectId, sizeof(OicUuid_t));
+ memcpy(&context->subject, subjectId, sizeof(OicUuid_t));
// Copy the resource string into context.
length = strlen(resource) + 1;
if(0 < length)
{
- OICFree(context->resource);
- context->resource = (char*)OICMalloc(length);
- VERIFY_NON_NULL(TAG, context->resource, ERROR);
strncpy(context->resource, resource, length);
context->resource[length - 1] = '\0';
}
// Assign the permission field.
context->permission = requestedPermission;
-
-exit:
- return;
}
+
/**
* Check whether 'resource' is getting accessed within the valid time period.
* @param acl The ACL to check.
return false;
}
+
/**
* Find ACLs containing context->subject.
* Search each ACL for requested resource.
- * If resource found, check for context->permission.
+ * If resource found, check for context->permission and period validity.
+ * If the ACL is not found locally and AMACL for the resource is found
+ * then sends the request to AMS service for the ACL
* Set context->retVal to result from first ACL found which contains
* correct subject AND resource.
*
// Start out assuming subject not found.
context->retVal = ACCESS_DENIED_SUBJECT_NOT_FOUND;
+
+ // Loop through all ACLs with a matching Subject searching for the right
+ // ACL for this request.
do
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): getting ACL...");
- currentAcl = GetACLResourceData(context->subject, &savePtr);
+ OC_LOG_V(INFO, TAG, ("%s: getting ACL..."),__func__);
+ currentAcl = GetACLResourceData(&context->subject, &savePtr);
+
if(NULL != currentAcl)
{
// Found the subject, so how about resource?
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- found ACL matching subject.");
+ OC_LOG_V(INFO, TAG, ("%s:found ACL matching subject"),__func__);
+
+ // Subject was found, so err changes to Rsrc not found for now.
context->retVal = ACCESS_DENIED_RESOURCE_NOT_FOUND;
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- Searching for resource...");
+ OC_LOG_V(INFO, TAG, ("%s:Searching for resource..."),__func__);
if(IsResourceInAcl(context->resource, currentAcl))
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- found matching resource in ACL.");
+ OC_LOG_V(INFO, TAG, ("%s:found matching resource in ACL"),__func__);
context->matchingAclFound = true;
// Found the resource, so it's down to valid period & permission.
if(IsAccessWithinValidTime(currentAcl))
{
context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION;
- if(IsPermissionAllowingRequest(currentAcl->permission, \
- context->permission))
+ if(IsPermissionAllowingRequest(currentAcl->permission, context->permission))
{
context->retVal = ACCESS_GRANTED;
}
}
else
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- no ACL found matching subject .");
+ OC_LOG_V(INFO, TAG, ("%s:no ACL found matching subject for resource %s"),__func__, context->resource);
}
}
while((NULL != currentAcl) && (false == context->matchingAclFound));
if(IsAccessGranted(context->retVal))
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- Leaving ProcessAccessRequest(ACCESS_GRANTED)");
+ OC_LOG_V(INFO, TAG, ("%s:Leaving ProcessAccessRequest(ACCESS_GRANTED)"), __func__);
}
else
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- Leaving ProcessAccessRequest(ACCESS_DENIED)");
+ OC_LOG_V(INFO, TAG, ("%s:Leaving ProcessAccessRequest(ACCESS_DENIED)"), __func__);
}
}
else
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- Leaving ProcessAccessRequest(context is NULL)");
+ OC_LOG_V(INFO, TAG, ("%s:Leaving ProcessAccessRequest(context is NULL)"), __func__);
}
-
}
/**
VERIFY_NON_NULL(TAG, resource, ERROR);
// Each state machine context can only be processing one request at a time.
- // Therefore if the context is not in AWAITING_REQUEST state, return error.
- // Otherwise, change to BUSY state and begin processing request.
- if(AWAITING_REQUEST == context->state)
+ // Therefore if the context is not in AWAITING_REQUEST or AWAITING_AMS_RESPONSE
+ // state, return error. Otherwise, change to BUSY state and begin processing request.
+ if(AWAITING_REQUEST == context->state || AWAITING_AMS_RESPONSE == context->state)
{
- SetPolicyEngineState(context, BUSY);
- CopyParamsToContext(context, subjectId, resource, requestedPermission);
+ if(AWAITING_REQUEST == context->state)
+ {
+ SetPolicyEngineState(context, BUSY);
+ CopyParamsToContext(context, subjectId, resource, requestedPermission);
+ }
+
// Before doing any processing, check if request coming
// from DevOwner and if so, always GRANT.
if(IsRequestFromDevOwner(context))
}
else
{
+ OicUuid_t saveSubject = {.id={}};
+ bool isSubEmpty = IsRequestSubjectEmpty(context);
+
ProcessAccessRequest(context);
+
// If matching ACL not found, and subject != wildcard, try wildcard.
if((false == context->matchingAclFound) && \
- (false == IsWildCardSubject(context->subject)))
+ (false == IsWildCardSubject(&context->subject)))
{
- OICFree(context->subject);
- context->subject = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, context->subject, ERROR);
- memcpy(context->subject, &WILDCARD_SUBJECT_ID,
- sizeof(OicUuid_t));
+ //Saving subject for Amacl check
+ memcpy(&saveSubject, &context->subject,sizeof(OicUuid_t));
+
+ //Setting context subject to WILDCARD_SUBJECT_ID
+ //TODO: change ProcessAccessRequest method signature to
+ //ProcessAccessRequest(context, subject) so that context
+ //subject is not tempered.
+ memset(&context->subject, 0, sizeof(context->subject));
+ memcpy(&context->subject, &WILDCARD_SUBJECT_ID,sizeof(OicUuid_t));
ProcessAccessRequest(context); // TODO anonymous subj can result
// in confusing err code return.
}
+
+ //No local ACE found for the request so checking Amacl resource
+ if(ACCESS_GRANTED != context->retVal)
+ {
+ //If subject is not empty then restore the original subject
+ //else keep the subject to WILDCARD_SUBJECT_ID
+ if(!isSubEmpty)
+ {
+ memcpy(&context->subject, &saveSubject, sizeof(OicUuid_t));
+ }
+
+ //FoundAmaclForRequest method checks for Amacl and fills up
+ //context->amsMgrContext->amsDeviceId with the AMS deviceId
+ //if Amacl was found for the requested resource.
+ if(FoundAmaclForRequest(context))
+ {
+ ProcessAMSRequest(context);
+ }
+ }
}
}
else
// Capture retVal before resetting state for next request.
retVal = context->retVal;
- SetPolicyEngineState(context, AWAITING_REQUEST);
+
+ //Change the state of PE to "AWAITING_AMS_RESPONSE", if waiting
+ //for response from AMS service else to "AWAITING_REQUEST"
+ if(ACCESS_WAITING_FOR_AMS == retVal)
+ {
+ OC_LOG(INFO, TAG, ("Setting PE State to AWAITING_AMS_RESPONSE"));
+ context->state = AWAITING_AMS_RESPONSE;
+ }
+ else if(!context->amsProcessing)
+ {
+ OC_LOG(INFO, TAG, ("Resetting PE context and PE State to AWAITING_REQUEST"));
+ SetPolicyEngineState(context, AWAITING_REQUEST);
+ }
exit:
return retVal;
*/
OCStackResult InitPolicyEngine(PEContext_t *context)
{
+ context->amsMgrContext = (AmsMgrContext_t *)OICMalloc(sizeof(AmsMgrContext_t));
if(NULL != context)
{
SetPolicyEngineState(context, AWAITING_REQUEST);
{
SetPolicyEngineState(context, STOPPED);
}
-
+ OICFree(context->amsMgrContext);
return;
}
#include "ocstack.h"
#include "logger.h"
#include "cainterface.h"
-#include "secureresourcemanager.h"
#include "resourcemanager.h"
#include "credresource.h"
#include "policyengine.h"
+#include "srmutility.h"
+#include "amsmgr.h"
#include "oic_string.h"
+#include "oic_malloc.h"
+#include "securevirtualresourcetypes.h"
+#include "secureresourcemanager.h"
#include <string.h>
#define TAG "SRM"
{
gSPResponseHandler = respHandler;
}
+
+
+static void SRMSendUnAuthorizedAccessresponse(PEContext_t *context)
+{
+ CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
+ memcpy(&responseInfo.info, &(context->amsMgrContext->requestInfo->info),
+ sizeof(responseInfo.info));
+ responseInfo.info.payload = NULL;
+ responseInfo.result = CA_UNAUTHORIZED_REQ;
+ if (CA_STATUS_OK != CASendResponse(context->amsMgrContext->endpoint, &responseInfo))
+ {
+ OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
+ }
+ else
+ {
+ OC_LOG(INFO, TAG, "Succeed in sending response to a unauthorized request!");
+ }
+}
+
+
+void SRMSendResponse(SRMAccessResponse_t responseVal)
+{
+ OC_LOG(INFO, TAG, "Sending response to remote device");
+
+ if (IsAccessGranted(responseVal) && gRequestHandler)
+ {
+ OC_LOG_V(INFO, TAG, "%s : Access granted. Passing Request to RI layer", __func__);
+ if (!g_policyEngineContext.amsMgrContext->endpoint ||
+ !g_policyEngineContext.amsMgrContext->requestInfo)
+ {
+ OC_LOG_V(ERROR, TAG, "%s : Invalid arguments", __func__);
+ SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext);
+ goto exit;
+ }
+ gRequestHandler(g_policyEngineContext.amsMgrContext->endpoint,
+ g_policyEngineContext.amsMgrContext->requestInfo);
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "%s : ACCESS_DENIED.", __func__);
+ SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext);
+ }
+
+exit:
+ //Resting PE state to AWAITING_REQUEST
+ SetPolicyEngineState(&g_policyEngineContext, AWAITING_REQUEST);
+}
+
+
/**
* @brief Handle the request from the SRM.
* @param endPoint [IN] Endpoint object from which the response is received.
int position = 0;
if (uri)
{
+ //Skip query and pass the resource uri
position = uri - requestInfo->info.resourceUri;
}
- if (position > MAX_URI_LENGTH)
+ else
+ {
+ position = strlen(requestInfo->info.resourceUri);
+ }
+ if (MAX_URI_LENGTH < position || 0 > position)
{
- OC_LOG(ERROR, TAG, "URI length is too long");
+ OC_LOG(ERROR, TAG, "Incorrect URI length");
return;
}
SRMAccessResponse_t response = ACCESS_DENIED;
- if (position > 0)
+ char newUri[MAX_URI_LENGTH + 1];
+ OICStrcpyPartial(newUri, MAX_URI_LENGTH + 1, requestInfo->info.resourceUri, position);
+
+ //New request are only processed if the policy engine state is AWAITING_REQUEST.
+ if(AWAITING_REQUEST == g_policyEngineContext.state)
{
- char newUri[MAX_URI_LENGTH + 1];
- OICStrcpyPartial(newUri, MAX_URI_LENGTH + 1, requestInfo->info.resourceUri, position);
- //Skip query and pass the newUri.
- response = CheckPermission(&g_policyEngineContext, &subjectId,
- newUri,
- GetPermissionFromCAMethod_t(requestInfo->method));
+ OC_LOG_V(INFO, TAG, "Processing request with uri, %s for method, %d",
+ requestInfo->info.resourceUri, requestInfo->method);
+ response = CheckPermission(&g_policyEngineContext, &subjectId, newUri,
+ GetPermissionFromCAMethod_t(requestInfo->method));
}
else
{
- //Pass resourceUri if there is no query info.
- response = CheckPermission(&g_policyEngineContext, &subjectId,
- requestInfo->info.resourceUri,
- GetPermissionFromCAMethod_t(requestInfo->method));
+ OC_LOG_V(INFO, TAG, "PE state %d. Ignoring request with uri, %s for method, %d",
+ g_policyEngineContext.state, requestInfo->info.resourceUri, requestInfo->method);
}
+
if (IsAccessGranted(response) && gRequestHandler)
{
return (gRequestHandler(endPoint, requestInfo));
}
- // Form a 'access deny' or 'Error' response and send to peer
+ // Form a 'Error', 'slow response' or 'access deny' response and send to peer
CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
memcpy(&responseInfo.info, &(requestInfo->info), sizeof(responseInfo.info));
responseInfo.info.payload = NULL;
- if (!gRequestHandler)
+
+ VERIFY_NON_NULL(TAG, gRequestHandler, ERROR);
+
+ if(ACCESS_WAITING_FOR_AMS == response)
{
- responseInfo.result = CA_INTERNAL_SERVER_ERROR;
+ OC_LOG(INFO, TAG, "Sending slow response");
+
+ UpdateAmsMgrContext(&g_policyEngineContext, endPoint, requestInfo);
+ responseInfo.result = CA_EMPTY;
+ responseInfo.info.type = CA_MSG_ACKNOWLEDGE;
}
else
{
* CA_UNAUTHORIZED_REQ or CA_FORBIDDEN_REQ depending
* upon SRMAccessResponseReasonCode_t
*/
+ OC_LOG(INFO, TAG, "Sending for regular response");
responseInfo.result = CA_UNAUTHORIZED_REQ;
}
{
OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
}
+ return;
+exit:
+ responseInfo.result = CA_INTERNAL_SERVER_ERROR;
+ if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo))
+ {
+ OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
+ }
}
/**
*/
void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
{
- OC_LOG(INFO, TAG, "Received error from remote device");
+ OC_LOG_V(INFO, TAG, "Received error from remote device with result, %d for request uri, %s",
+ errorInfo->result, errorInfo->info.resourceUri);
if (gErrorHandler)
{
gErrorHandler(endPoint, errorInfo);
{
DeInitPolicyEngine(&g_peContext);
EXPECT_EQ(STOPPED, g_peContext.state);
- EXPECT_EQ(NULL, g_peContext.subject);
- EXPECT_EQ(NULL, g_peContext.resource);
EXPECT_EQ((uint16_t)0, g_peContext.permission);
EXPECT_FALSE(g_peContext.matchingAclFound);
EXPECT_EQ(ACCESS_DENIED_POLICY_ENGINE_ERROR, g_peContext.retVal);
--- /dev/null
+Testing AMS service:
+1. Copy subjectID ("NDQ0NDMzMzMyMjIyMTExMQ==") of ACE with resource "/a/led" from AMS service
+ database file, "oic_amss_db.json" into client Doxm resource deviceID located in file
+ "oic_svr_client.json".
+2. Start ocserverbasicops
+3. start ocamsservice
+4. Start occlientbasicops
+
+
+Expected Result:
+1. New ACE with subjectID="NDQ0NDMzMzMyMjIyMTExMQ==" and rsrc="/a/led/" will be appended to the
+ server ACL resource in file "oic_svr_db_server.json".
+2. GET request made by occlientbasicops will be received successfully
+3. PUT reuest will received with result "OC_STACK_UNAUTHORIZED_REQ"
ocserverbasicops = samples_env.Program('ocserverbasicops', ['common.cpp', 'ocserverbasicops.cpp'])
occlientbasicops = samples_env.Program('occlientbasicops', ['common.cpp', 'occlientbasicops.cpp'])
+ocamsservice = samples_env.Program('ocamsservice', ['common.cpp', 'ocamsservice.cpp'])
-Alias("samples", [ocserverbasicops, occlientbasicops])
+Alias("samples", [ocserverbasicops, occlientbasicops, ocamsservice])
env.AppendTarget('samples')
sec_samples_src_dir + 'oic_svr_db_server.json'))
samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
sec_samples_src_dir + 'oic_svr_db_client.json'))
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
+ sec_samples_src_dir + 'oic_amss_db.json'))
--- /dev/null
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+#include "ocstack.h"
+#include "logger.h"
+#include "common.h"
+
+#define TAG PCF("SRM-AMSS")
+
+int gQuitFlag = 0;
+
+//AMS service database, hold AMS service Identity and
+//the PSK credentials of trusted devices
+static char AMSS_DB_FILE[] = "oic_amss_db.json";
+
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+ if (signum == SIGINT)
+ {
+ gQuitFlag = 1;
+ }
+}
+
+FILE* service_fopen(const char *path, const char *mode)
+{
+ (void)path;
+ return fopen(AMSS_DB_FILE, mode);
+}
+
+int main(int /*argc*/, char* /*argv*/[])
+{
+ struct timespec timeout;
+
+ OC_LOG(DEBUG, TAG, "OCAMS service is starting...");
+
+ // Initialize Persistent Storage for SVR database
+ OCPersistentStorage ps = { service_fopen, fread, fwrite, fclose, unlink };
+ OCRegisterPersistentStorageHandler(&ps);
+
+ if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack init error");
+ return 0;
+ }
+
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 100000000L;
+
+ // Break from loop with Ctrl-C
+ OC_LOG(INFO, TAG, "Entering ocamsservice main loop...");
+ signal(SIGINT, handleSigInt);
+ while (!gQuitFlag)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ return 0;
+ }
+ nanosleep(&timeout, NULL);
+ }
+
+ OC_LOG(INFO, TAG, "Exiting ocamsservice main loop...");
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ }
+
+ return 0;
+}
--- /dev/null
+{
+ "acl": [
+ {
+ "sub": "Kg==",
+ "rsrc": [
+ "/oic/res",
+ "/oic/d",
+ "/oic/p",
+ "/oic/res/types/d",
+ "/oic/ad",
+ "/oic/sec/acl",
+ "/oic/sec/amacl"
+ ],
+ "perms": 2,
+ "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+ },
+ {
+ "sub": "Kg==",
+ "rsrc": [
+ "/oic/sec/doxm",
+ "/oic/sec/pstat"
+ ],
+ "perms": 2,
+ "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+ },
+ {
+ "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
+ "rsrc": ["/oic/sec/acl",
+ "/oic/sec/cred"],
+ "perms": 8,
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ },
+ {
+ "sub": "NDQ0NDMzMzMyMjIyMTExMQ==",
+ "rsrc": ["/a/led"],
+ "perms": 6,
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }
+ ],
+ "pstat": {
+ "isop": true,
+ "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
+ "ch": 0,
+ "cm": 0,
+ "tm": 0,
+ "om": 3,
+ "sm": [3]
+ },
+ "doxm": {
+ "oxm": [0],
+ "oxmsel": 0,
+ "sct": 1,
+ "owned": true,
+ "deviceid": "MTkxOTE5MTkxOTE5MTkxOQ==",
+ "ownr": "YWRtaW5EZXZpY2VVVUlEAA=="
+ },
+ "cred": [{
+ "credid": 1,
+ "sub": "MTExMTExMTExMTExMTExMQ==",
+ "credtyp": 1,
+ "pvdata": "QkJCQkJCQkJCQkJCQkJCQg==",
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }]
+}
"ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
}
],
+ "amacl": [{
+ "rsrc" : ["/a/led"],
+ "amss" : ["MTkxOTE5MTkxOTE5MTkxOQ=="],
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }],
"pstat": {
"isop": true,
"deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
"credtyp": 1,
"pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
"ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ },
+ {
+ "credid": 4,
+ "sub": "NDQ0NDMzMzMyMjIyMTExMQ==",
+ "credtyp": 1,
+ "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ },
+ {
+ "credid": 5,
+ "sub": "MTkxOTE5MTkxOTE5MTkxOQ==",
+ "credtyp": 1,
+ "pvdata": "QkJCQkJCQkJCQkJCQkJCQg==",
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
}]
}
# Note: 'pthread' is in libc for android. On other platform, if use
# new gcc(>4.9?) it isn't required, otherwise, it's required
if target_os != 'android':
- examples_env.AppendUnique(LIBS = ['-lpthread'])
+ examples_env.AppendUnique(LIBS = ['-lpthread', '-ldl'])
examples_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
examples_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
])
provisiontests_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
-provisiontests_env.AppendUnique(LIBS = ['-lpthread'])
+provisiontests_env.AppendUnique(LIBS = ['-lpthread', '-ldl'])
provisiontests_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
provisiontests_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
provisiontests_env.PrependUnique(LIBS = [