diff --git a/CHANGELOG b/CHANGELOG index 4f462269..0f908248 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,8 +1,99 @@ -Changes to version 1.5.1 +Changes to version 1.5.3 ------------------------ New features and improvements: +- config file parser dynamically allocates linebuffer to allow multithreaded applications (#484) +- parse time values in model configuration file (LIB61850-426) +- config file generator: added missing code for GSEControl (LIB61850-418) +- Config file generator: support multiple access points for GOOSE and SMV control blocks (LIB61850-418) +- config file generator: added code to add SMVCBs to config files (LIB61850-67) +- IED server: added code to create SMVCBs with the dynamic model API (LIB61850-67) +- MMS server: added support for write access with component alternate access (LIB61850-414) +- MMS client: added function MmsConnection_writeVariableComponent to write to variables with alternate component access (LIB61850-414) +- make write access to RCB elements configurable according to ReportSettings (LIB61850-404) +- Added function IedConnection_setLocalAddress to define local IP address and optionally local port of a client connection (LIB61850-378) +- IED server: added ControlAction_getSynchroCheck and ControlAction_getInterlockCheck functions + + +Fixed bugs and vulnerabilities: + +- fixed - IEC 61580 server: dataset is not released when RCB.Datset is set to empty string by client (LIB61850-425) +- PAL: fixed wrong order of function arguments for fread and fwrite functions +- MMS client: parsing of servicecsSupported in MMS init response is off by one (LIB61850-419)(#469) +- fixed - potential memory leaks in goose publisher code (#464) +- fixed - server sends dchg report when only dupd is enabled in RCB (LIB61850-411) +- GOOSE subscriber: fixed - possible heap corruption in parseAllData due to missing validity check in bit-string handling (LIB61850-402) +- IED server: fixed problem with implicit ResvTms setting when reserved with RptEna (LIB61850-400) +- IED server: fixed - segmentation fault when compiled with CONFIG_MMS_THREADLESS_STACK (LIB61850-398) +- fixed - MMS server: messages can be corrupted when TCP buffer is full (LIB61850-385) +- fixed - .NET: IedConenction.WriteDataSetValues throws a NullReferenceException (LIB61850-384) +- fixed - server send invalid response- when client uses wrong ctlModel (LIB61850-383) (#435) +- fixed - IedConnection_setRCBValuesAsync crashes when RCB is already reserved by other client (LIB61850-382) +- fixed - outstanding call not released in IedConnection_getDataSetDirectoryAsync (LIB61850-379) + + +Changes to version 1.5.2 (Dec 19, 2022) +--------------------------------------- + +New features and improvements: + +- renamed TLSConfiguration_EventLevel to TLSEventLevel +- updated required mbedtls version to 2.28.x +- Added check for changed CRL on socket read/write. Added reset of renegotiation ssl cache on CRL add +- Fixing Security events messages to match IEC62351-100-3 +- .NET API: Added support for TLS event handler (LIB61850-373) +- IED Server: added function to set time quality for internally updated times (LIB61850-372) +- added TLSConnection object to provide more context in TLS event callback (LIB61850-366) +- TLS: added TLS alert callbacks; support for session resumption with session IDs (LIB61850-339) +- MMS client: added function MmsConnection_sendRawData for test purposes +- changed StringUtils_createStringInBuffer function to consider max buffer size (LIB61850-333) +- replaced most str(n)cpy/str(n)cat calls (LIB61850-333) +- encode boolean true value as 0x01 instead of 0xff to avoid interoperability problems +- added IedServerConfig_setSyncIntegrityReportTimes/IedServerConfig_setSyncIntegrityReportTimes wrapper to .NET API (LIB61850-323) +- added feature: synchronization of integrity report times (LIB61850-323) +- server: added RCBEventHandler event types REPORT_CREATED and OVERFLOW +- added function ReportControlBlock_getResv +- mms_utility: added option to read data set directory +- .NET API: added IedServer.GetFunctionalConstrainedData method (LIB61850-317) +- RCBEventHandler: replaced GI event by purgeBuf event when client disables RCB instance (LIB61850-316) +- enabled TLS 1.2 support in mbedtls configuration +- improved MmsValue handling; fixed MmsValue(OCTET-STRIG) maximum size problem (LIB61850-150) +- IED server: improved control state machine performance (LIB61850-312) + +Fixed bugs and vulnerabilities: + +- fixed - dynamic model helper functions: Check added to Cancel object for CDC APC +- fixed wrong number in TLS event code define (LIB61850_366) +- fixed - servers sends object-access-unsupported on GetAllData when ReadAccessHandler is installed (LIB61850-370) +- fixed - endless loop sending reports when MMS PDU size is too small (LIB61850-365) +- fixed path traversal vulnerability in MMS file services (LIB61850-357) +- IED server: added missing call to getNextRoundedStartTime (LIB61850-323) +- fixed - server crashs when SyncIntegrityReportTimes is active and IntgPd=0 (LIB61850-355) +- fixed - missing API export declarations for functions IedServerConfig_setSyncIntegrityReportTimes and IedServerConfig_getSyncIntegrityReportTimes (LIB61850-353) +- IED server: fixed - possible deadlock when IedServer_lockDataModel is used from multiple threads (LIB61850-352) +- MMS server: fixed - possible deadlock in obtainFile-service/file upload task (LIB61850-351) +- MMS server: fixed potential null pointer dereference when confirmeServiceResponse for fileOpen is received with invoke-id 0 (LIB61850-348) +- MMS_SERVER: fixed bug in getNameList request handling when domain ID is too long (LIB61850-346) +- GOOSE subscriber: fixed vulnerabilities related to malformed bit-string, integer, and unsigned values (LIB61850-342) +- MMS server: fixed bug in handling of continueAfter parameter of getNameList request (LIB61850-341) +- fixed sscanf format string in config_file_parser.c +- fixed locking mechanism in logging.c (LIB61850-327) +- fixed problem: negative presentation layer and ACSE results are ignored by client +- fixed wrong buffer size in client side report handling +- fixed memory leak in server read request handling (LIB61850-325) +- fixed memory leak in reuse of client connection (related to socket extension buffer) +- fixed - TLS: CRL is ignored +- fixed wrong MMS protocol version check (#379) +- fixed - SV publisher encoding problem when svID or datset length > 127 bytes (LIB61850-315)(#382) +- IedServerConfig: added missing variable initialization +- fixed - server doesn't respond SBOw when waiting for select callback (LIB61850-313) + +Changes to version 1.5.1 (Mar 11, 2022) +--------------------------------------- + +New features and improvements: + - added server side ReportControlBlock events and value access functions - added functions Timestamp_fromMmsValue and Quality_toMmsValue - made server report reservation compatible with Ed. 2.1 (LIB61850-293) diff --git a/CMakeLists.txt b/CMakeLists.txt index 203d44d5..7f9a1c9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ ENABLE_TESTING() set(LIB_VERSION_MAJOR "1") set(LIB_VERSION_MINOR "5") -set(LIB_VERSION_PATCH "2") +set(LIB_VERSION_PATCH "3") set(LIB_VERSION "${LIB_VERSION_MAJOR}.${LIB_VERSION_MINOR}.${LIB_VERSION_PATCH}") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/third_party/cmake/modules/") diff --git a/hal/filesystem/win32/file_provider_win32.c b/hal/filesystem/win32/file_provider_win32.c index b51a1a45..f5db69a4 100644 --- a/hal/filesystem/win32/file_provider_win32.c +++ b/hal/filesystem/win32/file_provider_win32.c @@ -21,6 +21,8 @@ * See COPYING file for the complete license text. */ +#define _CRT_SECURE_NO_WARNINGS + #include #include #include @@ -62,13 +64,13 @@ FileSystem_openFile(char* fileName, bool readWrite) int FileSystem_readFile(FileHandle handle, uint8_t* buffer, int maxSize) { - return fread(buffer, 1, maxSize, (FILE*) handle); + return (int)fread(buffer, 1, maxSize, (FILE*) handle); } int FileSystem_writeFile(FileHandle handle, uint8_t* buffer, int size) { - return fwrite(buffer, 1, size, (FILE*) handle); + return (int)fwrite(buffer, 1, size, (FILE*) handle); } void diff --git a/hal/socket/win32/socket_win32.c b/hal/socket/win32/socket_win32.c index 65be99d7..46a40d49 100644 --- a/hal/socket/win32/socket_win32.c +++ b/hal/socket/win32/socket_win32.c @@ -105,7 +105,7 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) memcpy((void*)&handles, &(self->handles), sizeof(fd_set)); - result = select(self->maxHandle + 1, &handles, NULL, NULL, &timeout); + result = select(0, &handles, NULL, NULL, &timeout); } else { result = -1; } @@ -436,7 +436,7 @@ Socket_checkAsyncConnectState(Socket self) FD_ZERO(&fdSet); FD_SET(self->fd, &fdSet); - int selectVal = select(self->fd + 1, NULL, &fdSet , NULL, &timeout); + int selectVal = select(0, NULL, &fdSet , NULL, &timeout); if (selectVal == 1) { @@ -489,7 +489,7 @@ Socket_connect(Socket self, const char* address, int port) FD_ZERO(&fdSet); FD_SET(self->fd, &fdSet); - if (select(self->fd + 1, NULL, &fdSet , NULL, &timeout) == 1) { + if (select(0, NULL, &fdSet , NULL, &timeout) == 1) { /* Check if connection is established */ diff --git a/hal/thread/win32/thread_win32.c b/hal/thread/win32/thread_win32.c index 7b17401d..33e7f091 100644 --- a/hal/thread/win32/thread_win32.c +++ b/hal/thread/win32/thread_win32.c @@ -7,6 +7,8 @@ * for libiec61850, libmms, and lib60870. */ +#define _CRT_SECURE_NO_WARNINGS + #include #include "lib_memory.h" #include "hal_thread.h" @@ -38,7 +40,9 @@ threadRunner(LPVOID parameter) { Thread thread = (Thread) parameter; - return (UINT) thread->function(thread->parameter); + thread->function(thread->parameter); + + return (DWORD)0; } Thread diff --git a/src/common/inc/libiec61850_platform_includes.h b/src/common/inc/libiec61850_platform_includes.h index c4414a6f..a33abeb1 100644 --- a/src/common/inc/libiec61850_platform_includes.h +++ b/src/common/inc/libiec61850_platform_includes.h @@ -17,7 +17,7 @@ #include "platform_endian.h" -#define LIBIEC61850_VERSION "1.5.2" +#define LIBIEC61850_VERSION "1.5.3" #ifndef CONFIG_DEFAULT_MMS_VENDOR_NAME #define CONFIG_DEFAULT_MMS_VENDOR_NAME "libiec61850.com" diff --git a/src/iec61850/server/mms_mapping/reporting.c b/src/iec61850/server/mms_mapping/reporting.c index cba98b86..9e37cee3 100644 --- a/src/iec61850/server/mms_mapping/reporting.c +++ b/src/iec61850/server/mms_mapping/reporting.c @@ -685,9 +685,23 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, success = true; dataSetValue = NULL; - if (rc->buffered) { - rc->isBuffering = false; - purgeBuf(rc); + if (rc->dataSet) { + if (rc->buffered) { + rc->isBuffering = false; + purgeBuf(rc); + } + + /* delete pending events */ + deleteDataSetValuesShadowBuffer(rc); + + if (rc->isDynamicDataSet) { + if (rc->dataSet) { + MmsMapping_freeDynamicallyCreatedDataSet(rc->dataSet); + } + } + + /* release used data set */ + rc->dataSet = NULL; } } else @@ -700,7 +714,6 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, /* check if old and new data sets are the same */ if (rc->dataSet && dataSetValue) { - const char* dataSetLdName = rc->dataSet->logicalDeviceName; const char* dataSetName = rc->dataSet->name; const char* newDataSetName = MmsValue_toString(dataSetValue); @@ -737,16 +750,7 @@ updateReportDataset(MmsMapping* mapping, ReportControl* rc, MmsValue* newDatSet, } } - if (rc->isDynamicDataSet) { - if (rc->dataSet && dataSetChanged) { - deleteDataSetValuesShadowBuffer(rc); - MmsMapping_freeDynamicallyCreatedDataSet(rc->dataSet); - rc->isDynamicDataSet = false; - rc->dataSet = NULL; - } - } - - if (dataSetValue && dataSetChanged) { + if (dataSetValue) { const char* dataSetName = MmsValue_toString(dataSetValue); DataSet* dataSet = IedModel_lookupDataSet(mapping->model, dataSetName); diff --git a/src/iec61850/server/model/config_file_parser.c b/src/iec61850/server/model/config_file_parser.c index 8846ea8b..65d5847c 100644 --- a/src/iec61850/server/model/config_file_parser.c +++ b/src/iec61850/server/model/config_file_parser.c @@ -31,8 +31,6 @@ #define READ_BUFFER_MAX_SIZE 1024 -static uint8_t lineBuffer[READ_BUFFER_MAX_SIZE]; - static int readLine(FileHandle fileHandle, uint8_t* buffer, int maxSize) { @@ -118,6 +116,11 @@ ConfigFileParser_createModelFromConfigFileEx(const char* filename) IedModel* ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle) { + uint8_t* lineBuffer = (uint8_t*)GLOBAL_MALLOC(READ_BUFFER_MAX_SIZE); + + if (lineBuffer == NULL) + goto exit_error; + int bytesRead = 1; bool stateInModel = false; @@ -541,8 +544,6 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle) else goto exit_error; } - - } else { if (StringUtils_startsWith((char*) lineBuffer, "MODEL{")) { @@ -564,14 +565,18 @@ ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle) } } + GLOBAL_FREEMEM(lineBuffer); + return model; exit_error: + + GLOBAL_FREEMEM(lineBuffer); + if (DEBUG_IED_SERVER) printf("IED_SERVER: error parsing line %i (indentation level = %i)\n", currentLine, indendation); IedModel_destroy(model); + return NULL; } - -