- IED server access control: Added IedServer_ControlBlockAccessHandler to control read and write access to control blocks. Implemented for SGCBs, RCBs, LCBs. (LIB61850-420)

v1.6_develop_417_rbac2
Michael Zillgith 2 years ago
parent cb1774f33d
commit ad26795465

@ -2035,6 +2035,17 @@ typedef bool
LIB61850_API void LIB61850_API void
IedServer_setListObjectsAccessHandler(IedServer self, IedServer_ListObjectsAccessHandler handler, void* parameter); IedServer_setListObjectsAccessHandler(IedServer self, IedServer_ListObjectsAccessHandler handler, void* parameter);
typedef enum {
IEC61850_CB_ACCESS_TYPE_READ,
IEC61850_CB_ACCESS_TYPE_WRITE
} IedServer_ControlBlockAccessType;
typedef bool
(*IedServer_ControlBlockAccessHandler)(void* parameter, ClientConnection connection, ACSIClass acsiClass, LogicalDevice* ld, LogicalNode* ln, const char* objectName, const char* subObjectName, IedServer_ControlBlockAccessType accessType);
LIB61850_API void
IedServer_setControlBlockAccessHandler(IedServer self, IedServer_ControlBlockAccessHandler handler, void* parameter);
/**@}*/ /**@}*/
/**@}*/ /**@}*/

@ -355,6 +355,9 @@ struct sMmsMapping {
IedServer_ListObjectsAccessHandler listObjectsAccessHandler; IedServer_ListObjectsAccessHandler listObjectsAccessHandler;
void* listObjectsAccessHandlerParameter; void* listObjectsAccessHandlerParameter;
IedServer_ControlBlockAccessHandler controlBlockAccessHandler;
void* controlBlockAccessHandlerParameter;
}; };
#endif /* MMS_MAPPING_INTERNAL_H_ */ #endif /* MMS_MAPPING_INTERNAL_H_ */

@ -1974,3 +1974,10 @@ IedServer_setListObjectsAccessHandler(IedServer self, IedServer_ListObjectsAcces
self->mmsMapping->listObjectsAccessHandler = handler; self->mmsMapping->listObjectsAccessHandler = handler;
self->mmsMapping->listObjectsAccessHandlerParameter = parameter; self->mmsMapping->listObjectsAccessHandlerParameter = parameter;
} }
void
IedServer_setControlBlockAccessHandler(IedServer self, IedServer_ControlBlockAccessHandler handler, void* parameter)
{
self->mmsMapping->controlBlockAccessHandler = handler;
self->mmsMapping->controlBlockAccessHandlerParameter = parameter;
}

@ -524,6 +524,7 @@ LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* doma
} }
else else
{ {
//TODO RBAC2 remove!?
if (self->lcbAccessHandler) if (self->lcbAccessHandler)
{ {
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection);
@ -534,6 +535,32 @@ LIBIEC61850_LOG_SVC_writeAccessLogControlBlock(MmsMapping* self, MmsDomain* doma
goto exit_function; goto exit_function;
} }
} }
if (self->controlBlockAccessHandler) {
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection);
LogicalDevice* ld = IedModel_getDevice(self->model, domain->domainName);
if (ld) {
LogicalNode* ln = LogicalDevice_getLogicalNode(ld, lnName);
if (ln) {
if (self->controlBlockAccessHandler(self->controlBlockAccessHandlerParameter, clientConnection, ACSI_CLASS_LCB, ld, ln, logControl->name, varName, IEC61850_CB_ACCESS_TYPE_WRITE) == false) {
retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
}
}
else {
retVal = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
}
}
else {
retVal = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
}
if (retVal != DATA_ACCESS_ERROR_SUCCESS) {
goto exit_function;
}
}
} }
if (strcmp(varName, "LogEna") == 0) { if (strcmp(varName, "LogEna") == 0) {
@ -747,6 +774,7 @@ LIBIEC61850_LOG_SVC_readAccessControlBlock(MmsMapping* self, MmsDomain* domain,
{ {
bool allowAccess = true; bool allowAccess = true;
//TODO RBAC2 remove?!
if (self->lcbAccessHandler) if (self->lcbAccessHandler)
{ {
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection);
@ -758,6 +786,24 @@ LIBIEC61850_LOG_SVC_readAccessControlBlock(MmsMapping* self, MmsDomain* domain,
} }
} }
if (self->controlBlockAccessHandler) {
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection);
LogicalDevice* ld = IedModel_getDevice(self->model, domain->domainName);
if (ld) {
LogicalNode* ln = LogicalDevice_getLogicalNode(ld, lnName);
if (ln) {
if (self->controlBlockAccessHandler(self->controlBlockAccessHandlerParameter, clientConnection, ACSI_CLASS_LCB, ld, ln, logControl->name, varName, IEC61850_CB_ACCESS_TYPE_READ) == false) {
allowAccess = false;
value = &objectAccessDenied;
}
}
}
}
if (allowAccess) { if (allowAccess) {
updateLogStatusInLCB(logControl); updateLogStatusInLCB(logControl);

@ -2701,6 +2701,42 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
char* nameId = nextSep + 1; char* nameId = nextSep + 1;
/* check access permissions */
if (self->controlBlockAccessHandler)
{
MmsDataAccessError retVal = DATA_ACCESS_ERROR_SUCCESS;
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer,
connection);
LogicalDevice* ld = IedModel_getDevice(self->model, domain->domainName);
if (ld) {
char lnName[65];
strncpy(lnName, variableId, 64);
lnName[64] = 0;
lnName[lnNameLength] = 0;
LogicalNode* ln = LogicalDevice_getLogicalNode(ld, lnName);
if (ln) {
if (self->controlBlockAccessHandler(self->controlBlockAccessHandlerParameter, clientConnection, ACSI_CLASS_SGCB, ld, ln, "SGCB", nameId, IEC61850_CB_ACCESS_TYPE_WRITE) == false) {
retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
}
}
else {
retVal = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
}
}
else {
retVal = DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT;
}
if (retVal != DATA_ACCESS_ERROR_SUCCESS) {
return retVal;
}
}
if (strcmp(nameId, "ActSG") == 0) { if (strcmp(nameId, "ActSG") == 0) {
SettingGroup* sg = getSettingGroupByMmsDomain(self, domain); SettingGroup* sg = getSettingGroupByMmsDomain(self, domain);
MmsDataAccessError retVal = DATA_ACCESS_ERROR_SUCCESS; MmsDataAccessError retVal = DATA_ACCESS_ERROR_SUCCESS;
@ -2709,6 +2745,7 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
uint32_t val = MmsValue_toUint32(value); uint32_t val = MmsValue_toUint32(value);
if ((val > 0) && (val <= sg->sgcb->numOfSGs)) { if ((val > 0) && (val <= sg->sgcb->numOfSGs)) {
if (val != sg->sgcb->actSG) { if (val != sg->sgcb->actSG) {
if (sg->actSgChangedHandler) { if (sg->actSgChangedHandler) {
@ -3640,8 +3677,17 @@ mmsReadAccessHandler (void* parameter, MmsDomain* domain, char* variableId, MmsS
} }
if (fc == IEC61850_FC_SP) { if (fc == IEC61850_FC_SP) {
if (!strcmp(str, "SGCB")) { if (!strcmp(str, "SGCB"))
//TODO RBAC2 add callback {
if (self->controlBlockAccessHandler) {
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer,
connection);
if (self->controlBlockAccessHandler(self->controlBlockAccessHandlerParameter, clientConnection, ACSI_CLASS_SGCB, ld, ln, str, "", IEC61850_CB_ACCESS_TYPE_READ) == false) {
return DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
}
}
return DATA_ACCESS_ERROR_SUCCESS; return DATA_ACCESS_ERROR_SUCCESS;
} }
} }

@ -1781,6 +1781,26 @@ ReportControl_readAccess(ReportControl* rc, MmsMapping* mmsMapping, MmsServerCon
clientConnection = private_IedServer_getClientConnectionByHandle(mmsMapping->iedServer, connection); clientConnection = private_IedServer_getClientConnectionByHandle(mmsMapping->iedServer, connection);
} }
if (mmsMapping->controlBlockAccessHandler)
{
ACSIClass acsiClass;
if (rc->rcb->buffered)
acsiClass = ACSI_CLASS_BRCB;
else
acsiClass = ACSI_CLASS_URCB;
LogicalNode* ln = rc->rcb->parent;
LogicalDevice* ld = (LogicalDevice*)ln->parent;
if (mmsMapping->controlBlockAccessHandler(mmsMapping->controlBlockAccessHandlerParameter, clientConnection, acsiClass, ld, ln, rc->name, elementName, IEC61850_CB_ACCESS_TYPE_READ) == false) {
accessError = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
accessAllowed = false;
}
}
//TODO RBAC2 remove?
if (mmsMapping->rcbAccessHandler) { if (mmsMapping->rcbAccessHandler) {
if (mmsMapping->rcbAccessHandler(mmsMapping->rcbAccessHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_GET_PARAMETER) == false) { if (mmsMapping->rcbAccessHandler(mmsMapping->rcbAccessHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_GET_PARAMETER) == false) {
accessError = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; accessError = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
@ -1890,7 +1910,7 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection); ClientConnection clientConnection = private_IedServer_getClientConnectionByHandle(self->iedServer, connection);
/* check if write access to RCB is allowed on this connection */ //TODO RBAC2 remove?
if (self->rcbAccessHandler) { if (self->rcbAccessHandler) {
if (self->rcbAccessHandler(self->rcbAccessHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_SET_PARAMETER) == false) { if (self->rcbAccessHandler(self->rcbAccessHandlerParameter, rc->rcb, clientConnection, RCB_EVENT_SET_PARAMETER) == false) {
retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED; retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
@ -1899,6 +1919,27 @@ Reporting_RCBWriteAccessHandler(MmsMapping* self, ReportControl* rc, char* eleme
} }
} }
/* check if write access to RCB is allowed on this connection */
if (self->controlBlockAccessHandler)
{
ACSIClass acsiClass;
if (rc->rcb->buffered)
acsiClass = ACSI_CLASS_BRCB;
else
acsiClass = ACSI_CLASS_URCB;
LogicalNode* ln = rc->rcb->parent;
LogicalDevice* ld = (LogicalDevice*)ln->parent;
if (self->controlBlockAccessHandler(self->controlBlockAccessHandlerParameter, clientConnection, acsiClass, ld, ln, rc->name, elementName, IEC61850_CB_ACCESS_TYPE_WRITE) == false) {
retVal = DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED;
goto exit_function_only_tracking;
}
}
/* check reservation timeout for buffered RCBs */ /* check reservation timeout for buffered RCBs */
if (rc->buffered) { if (rc->buffered) {

Loading…
Cancel
Save