X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fsecurity%2Fsrc%2Fsecureresourcemanager.c;h=a91b10f9732ebfd4c5b51265d2f1b312c15fca29;hb=ed12a86f1b4b488b08bc32d67009ab16df132cf1;hp=25602c30dfb5f2eaba5ed975a4e72783cea5b1a9;hpb=24c563ec03a6b314ab7c878d217ea83d02e5ecd9;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/security/src/secureresourcemanager.c b/resource/csdk/security/src/secureresourcemanager.c index 25602c3..a91b10f 100644 --- a/resource/csdk/security/src/secureresourcemanager.c +++ b/resource/csdk/security/src/secureresourcemanager.c @@ -18,6 +18,7 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#include #include "ocstack.h" #include "logger.h" #include "cainterface.h" @@ -30,9 +31,13 @@ #include "oic_malloc.h" #include "securevirtualresourcetypes.h" #include "secureresourcemanager.h" -#include +#include "srmresourcestrings.h" +#include "ocresourcehandler.h" -#define TAG "SRM" +#if defined( __WITH_TLS__) || defined(__WITH_DTLS__) +#include "pkix_interface.h" +#endif //__WITH_TLS__ or __WITH_DTLS__ +#define TAG "OIC_SRM" //Request Callback handler static CARequestCallback gRequestHandler = NULL; @@ -52,7 +57,7 @@ static SPResponseCallback gSPResponseHandler = NULL; PEContext_t g_policyEngineContext; /** - * @brief function to register provisoning API's response callback. + * Function to register provisoning API's response callback. * @param respHandler response handler callback. */ void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler) @@ -60,36 +65,49 @@ void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler) gSPResponseHandler = respHandler; } +void SetResourceRequestType(PEContext_t *context, const char *resourceUri) +{ + context->resourceType = GetSvrTypeFromUri(resourceUri); +} static void SRMSendUnAuthorizedAccessresponse(PEContext_t *context) { CAResponseInfo_t responseInfo = {.result = CA_EMPTY}; + + if (NULL == context || + NULL == context->amsMgrContext->requestInfo) + { + OIC_LOG_V(ERROR, TAG, "%s : NULL Parameter(s)",__func__); + return; + } + 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)) + responseInfo.info.dataType = CA_RESPONSE_DATA; + + if (CA_STATUS_OK == CASendResponse(context->amsMgrContext->endpoint, &responseInfo)) { - OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!"); + OIC_LOG(DEBUG, TAG, "Succeed in sending response to a unauthorized request!"); } else { - OC_LOG(INFO, TAG, "Succeed in sending response to a unauthorized request!"); + OIC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!"); } } - void SRMSendResponse(SRMAccessResponse_t responseVal) { - OC_LOG(INFO, TAG, "Sending response to remote device"); + OIC_LOG(DEBUG, TAG, "Sending response to remote device"); if (IsAccessGranted(responseVal) && gRequestHandler) { - OC_LOG_V(INFO, TAG, "%s : Access granted. Passing Request to RI layer", __func__); + OIC_LOG_V(INFO, TAG, "%s : Access granted. Passing Request to RI layer", __func__); if (!g_policyEngineContext.amsMgrContext->endpoint || - !g_policyEngineContext.amsMgrContext->requestInfo) + !g_policyEngineContext.amsMgrContext->requestInfo) { - OC_LOG_V(ERROR, TAG, "%s : Invalid arguments", __func__); + OIC_LOG_V(ERROR, TAG, "%s : Invalid arguments", __func__); SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext); goto exit; } @@ -98,37 +116,48 @@ void SRMSendResponse(SRMAccessResponse_t responseVal) } else { - OC_LOG_V(INFO, TAG, "%s : ACCESS_DENIED.", __func__); + OIC_LOG_V(INFO, TAG, "%s : ACCESS_DENIED.", __func__); SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext); } exit: - //Resting PE state to AWAITING_REQUEST + //Resetting 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. - * @param requestInfo [IN] Information for the request. - * @return NONE + * Handle the request from the SRM. + * + * @param endPoint object from which the response is received. + * @param requestInfo contains information for the request. */ void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requestInfo) { - OC_LOG(INFO, TAG, "Received request from remote device"); + OIC_LOG(DEBUG, TAG, "Received request from remote device"); + bool isRequestOverSecureChannel = false; if (!endPoint || !requestInfo) { - OC_LOG(ERROR, TAG, "Invalid arguments"); + OIC_LOG(ERROR, TAG, "Invalid arguments"); return; } // Copy the subjectID OicUuid_t subjectId = {.id = {0}}; memcpy(subjectId.id, requestInfo->info.identity.id, sizeof(subjectId.id)); + if (endPoint->flags & CA_SECURE) + { + OIC_LOG(INFO, TAG, "request over secure channel"); + isRequestOverSecureChannel = true; + } //Check the URI has the query and skip it before checking the permission + if (NULL == requestInfo->info.resourceUri) + { + OIC_LOG(ERROR, TAG, "Invalid resourceUri"); + return; + } + char *uri = strstr(requestInfo->info.resourceUri, "?"); int position = 0; if (uri) @@ -142,42 +171,79 @@ void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requ } if (MAX_URI_LENGTH < position || 0 > position) { - OC_LOG(ERROR, TAG, "Incorrect URI length"); + OIC_LOG(ERROR, TAG, "Incorrect URI length"); return; } SRMAccessResponse_t response = ACCESS_DENIED; char newUri[MAX_URI_LENGTH + 1]; OICStrcpyPartial(newUri, MAX_URI_LENGTH + 1, requestInfo->info.resourceUri, position); + SetResourceRequestType(&g_policyEngineContext, newUri); + + // 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; + responseInfo.info.dataType = CA_RESPONSE_DATA; + + OCResource *resPtr = FindResourceByUri(newUri); + if (NULL != resPtr) + { + // All vertical secure resources and SVR resources other than DOXM & PSTAT should reject request + // over coap. + if ((((resPtr->resourceProperties) & OC_SECURE) + && (g_policyEngineContext.resourceType == NOT_A_SVR_RESOURCE)) + || ((g_policyEngineContext.resourceType < OIC_SEC_SVR_TYPE_COUNT) + && (g_policyEngineContext.resourceType != OIC_R_DOXM_TYPE) + && (g_policyEngineContext.resourceType != OIC_R_PSTAT_TYPE))) + { + // if resource is secure and request is over insecure channel + if (!isRequestOverSecureChannel) + { + // Reject all the requests over coap for secure resource. + responseInfo.result = CA_FORBIDDEN_REQ; + if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo)) + { + OIC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!"); + } + return; + } + } + } +#ifdef _ENABLE_MULTIPLE_OWNER_ + /* + * In case of ACL and CRED, The payload required to verify the payload. + * Payload information will be used for subowner's permission verification. + */ + g_policyEngineContext.payload = (uint8_t*)requestInfo->info.payload; + g_policyEngineContext.payloadSize = requestInfo->info.payloadSize; +#endif //_ENABLE_MULTIPLE_OWNER_ + //New request are only processed if the policy engine state is AWAITING_REQUEST. - if(AWAITING_REQUEST == g_policyEngineContext.state) + if (AWAITING_REQUEST == g_policyEngineContext.state) { - OC_LOG_V(INFO, TAG, "Processing request with uri, %s for method, %d", + OIC_LOG_V(DEBUG, 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 { - OC_LOG_V(INFO, TAG, "PE state %d. Ignoring request with uri, %s for method, %d", + OIC_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)); + gRequestHandler(endPoint, requestInfo); + return; } - // 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; - VERIFY_NON_NULL(TAG, gRequestHandler, ERROR); - if(ACCESS_WAITING_FOR_AMS == response) + if (ACCESS_WAITING_FOR_AMS == response) { - OC_LOG(INFO, TAG, "Sending slow response"); + OIC_LOG(INFO, TAG, "Sending slow response"); UpdateAmsMgrContext(&g_policyEngineContext, endPoint, requestInfo); responseInfo.result = CA_EMPTY; @@ -190,32 +256,32 @@ void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requ * CA_UNAUTHORIZED_REQ or CA_FORBIDDEN_REQ depending * upon SRMAccessResponseReasonCode_t */ - OC_LOG(INFO, TAG, "Sending for regular response"); + OIC_LOG(INFO, TAG, "Sending for regular response"); responseInfo.result = CA_UNAUTHORIZED_REQ; } if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo)) { - OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!"); + OIC_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!"); + OIC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!"); } } /** - * @brief Handle the response from the SRM. - * @param endPoint [IN] The remote endpoint. - * @param responseInfo [IN] Response information from the endpoint. - * @return NONE + * Handle the response from the SRM. + * + * @param endPoint points to the remote endpoint. + * @param responseInfo contains response information from the endpoint. */ void SRMResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *responseInfo) { - OC_LOG(INFO, TAG, "Received response from remote device"); + OIC_LOG(DEBUG, TAG, "Received response from remote device"); // isProvResponse flag is to check whether response is catered by provisioning APIs or not. // When token sent by CA response matches with token generated by provisioning request, @@ -234,16 +300,15 @@ void SRMResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *re } } - /** - * @brief Handle the error from the SRM. - * @param endPoint [IN] The remote endpoint. - * @param errorInfo [IN] Error information from the endpoint. - * @return NONE + * Handle the error from the SRM. + * + * @param endPoint is the remote endpoint. + * @param errorInfo contains error information from the endpoint. */ void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo) { - OC_LOG_V(INFO, TAG, "Received error from remote device with result, %d for request uri, %s", + OIC_LOG_V(INFO, TAG, "Received error from remote device with result, %d for request uri, %s", errorInfo->result, errorInfo->info.resourceUri); if (gErrorHandler) { @@ -251,24 +316,14 @@ void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInf } } - -/** - * @brief Register request and response callbacks. - * Requests and responses are delivered in these callbacks. - * @param reqHandler [IN] Request handler callback ( for GET,PUT ..etc) - * @param respHandler [IN] Response handler callback. - * @return - * OC_STACK_OK - No errors; Success - * OC_STACK_INVALID_PARAM - invalid parameter - */ OCStackResult SRMRegisterHandler(CARequestCallback reqHandler, CAResponseCallback respHandler, CAErrorCallback errHandler) { - OC_LOG(INFO, TAG, "SRMRegisterHandler !!"); + OIC_LOG(DEBUG, TAG, "SRMRegisterHandler !!"); if( !reqHandler || !respHandler || !errHandler) { - OC_LOG(ERROR, TAG, "Callback handlers are invalid"); + OIC_LOG(ERROR, TAG, "Callback handlers are invalid"); return OC_STACK_INVALID_PARAM; } gRequestHandler = reqHandler; @@ -276,7 +331,7 @@ OCStackResult SRMRegisterHandler(CARequestCallback reqHandler, gErrorHandler = errHandler; -#if defined(__WITH_DTLS__) +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) CARegisterHandler(SRMRequestHandler, SRMResponseHandler, SRMErrorHandler); #else CARegisterHandler(reqHandler, respHandler, errHandler); @@ -284,77 +339,212 @@ OCStackResult SRMRegisterHandler(CARequestCallback reqHandler, return OC_STACK_OK; } -/** - * @brief Register Persistent storage callback. - * @param persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers. - * @return - * OC_STACK_OK - No errors; Success - * OC_STACK_INVALID_PARAM - Invalid parameter - */ OCStackResult SRMRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler) { - OC_LOG(INFO, TAG, "SRMRegisterPersistentStorageHandler !!"); + OIC_LOG(DEBUG, TAG, "SRMRegisterPersistentStorageHandler !!"); if(!persistentStorageHandler) { - OC_LOG(ERROR, TAG, "The persistent storage handler is invalid"); + OIC_LOG(ERROR, TAG, "The persistent storage handler is invalid"); return OC_STACK_INVALID_PARAM; } gPersistentStorageHandler = persistentStorageHandler; return OC_STACK_OK; } -/** - * @brief Get Persistent storage handler pointer. - * @return - * The pointer to Persistent Storage callback handler - */ - OCPersistentStorage* SRMGetPersistentStorageHandler() { return gPersistentStorageHandler; } - -/** - * @brief Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc). - * @retval OC_STACK_OK for Success, otherwise some error value - */ OCStackResult SRMInitSecureResources() { // TODO: temporarily returning OC_STACK_OK every time until default // behavior (for when SVR DB is missing) is settled. InitSecureResources(); - -#if defined(__WITH_DTLS__) - CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials); -#endif // (__WITH_DTLS__) - - return OC_STACK_OK; + OCStackResult ret = OC_STACK_OK; +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + if (CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials)) + { + OIC_LOG(ERROR, TAG, "Failed to revert TLS credential handler."); + ret = OC_STACK_ERROR; + } + CAregisterPkixInfoHandler(GetPkixInfo); + CAregisterGetCredentialTypesHandler(InitCipherSuiteList); +#endif // __WITH_DTLS__ or __WITH_TLS__ + return ret; } -/** - * @brief Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc). - * @retval none - */ void SRMDeInitSecureResources() { DestroySecureResources(); } -/** - * @brief Initialize Policy Engine. - * @return OC_STACK_OK for Success, otherwise some error value. - */ OCStackResult SRMInitPolicyEngine() { return InitPolicyEngine(&g_policyEngineContext); } +void SRMDeInitPolicyEngine() +{ + DeInitPolicyEngine(&g_policyEngineContext); +} + +bool SRMIsSecurityResourceURI(const char* uri) +{ + if (!uri) + { + return false; + } + + const char *rsrcs[] = { + OIC_RSRC_SVC_URI, + OIC_RSRC_AMACL_URI, + OIC_RSRC_CRL_URI, + OIC_RSRC_CRED_URI, + OIC_RSRC_ACL_URI, + OIC_RSRC_DOXM_URI, + OIC_RSRC_PSTAT_URI, + OIC_RSRC_PCONF_URI, + OIC_RSRC_DPAIRING_URI, + OIC_RSRC_VER_URI, + OC_RSRVD_PROV_CRL_URL + }; + + // Remove query from Uri for resource string comparison + size_t uriLen = strlen(uri); + char *query = strchr (uri, '?'); + if (query) + { + uriLen = query - uri; + } + + for (size_t i = 0; i < sizeof(rsrcs)/sizeof(rsrcs[0]); i++) + { + size_t svrLen = strlen(rsrcs[i]); + + if ((uriLen == svrLen) && + (strncmp(uri, rsrcs[i], svrLen) == 0)) + { + return true; + } + } + + return false; +} + /** - * @brief Cleanup Policy Engine. - * @return none + * Get the Secure Virtual Resource (SVR) type from the URI. + * @param uri [IN] Pointer to URI in question. + * @return The OicSecSvrType_t of the URI passed (note: if not a Secure Virtual + Resource, e.g. /a/light, will return "NOT_A_SVR_TYPE" enum value) */ -void SRMDeInitPolicyEngine() +static const char URI_QUERY_CHAR = '?'; +OicSecSvrType_t GetSvrTypeFromUri(const char* uri) { - return DeInitPolicyEngine(&g_policyEngineContext); + if (!uri) + { + return NOT_A_SVR_RESOURCE; + } + + // Remove query from Uri for resource string comparison + size_t uriLen = strlen(uri); + char *query = strchr (uri, URI_QUERY_CHAR); + if (query) + { + uriLen = query - uri; + } + + size_t svrLen = 0; + + svrLen = strlen(OIC_RSRC_ACL_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_ACL_URI, svrLen)) + { + return OIC_R_ACL_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_AMACL_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_AMACL_URI, svrLen)) + { + return OIC_R_AMACL_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_CRED_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_CRED_URI, svrLen)) + { + return OIC_R_CRED_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_CRL_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_CRL_URI, svrLen)) + { + return OIC_R_CRL_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_DOXM_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_DOXM_URI, svrLen)) + { + return OIC_R_DOXM_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_DPAIRING_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_DPAIRING_URI, svrLen)) + { + return OIC_R_DPAIRING_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_PCONF_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_PCONF_URI, svrLen)) + { + return OIC_R_PCONF_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_PSTAT_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_PSTAT_URI, svrLen)) + { + return OIC_R_PSTAT_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_SVC_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_SVC_URI, svrLen)) + { + return OIC_R_SVC_TYPE; + } + } + + svrLen = strlen(OIC_RSRC_SACL_URI); + if(uriLen == svrLen) + { + if(0 == strncmp(uri, OIC_RSRC_SACL_URI, svrLen)) + { + return OIC_R_SACL_TYPE; + } + } + + return NOT_A_SVR_RESOURCE; }