You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dcmtk/SOURCES/0019-CVE-2021-41687-CVE-202...

569 lines
20 KiB

From 2b026afd64f077b4f6276afc2fa9a885b8b47d38 Mon Sep 17 00:00:00 2001
From: Michael Onken <onken@open-connections.de>
Date: Sat, 2 Oct 2021 00:29:56 +0200
Subject: [PATCH 19/22] [CVE-2021-41687, CVE-2021-41688, CVE-2021-41690] Fixed
poss. NULL pointer dereference/double free.
Thanks to Jinsheng Ba <bajinsheng@u.nus.edu> for the report and some patches.
(cherry picked from commit a9697dfeb672b0b9412c00c7d36d801e27ec85cb)
---
.../dcmtk/dcmnet}/dulstruc.h | 8 ++
dcmnet/include/dcmtk/dcmnet/helpers.h | 38 +++++++
dcmnet/libsrc/CMakeLists.txt | 2 +-
dcmnet/libsrc/Makefile.in | 2 +-
dcmnet/libsrc/assoc.cc | 23 +---
dcmnet/libsrc/dcuserid.cc | 4 +-
dcmnet/libsrc/dul.cc | 2 +-
dcmnet/libsrc/dulconst.cc | 2 +-
dcmnet/libsrc/dulextra.cc | 2 +-
dcmnet/libsrc/dulfsm.cc | 51 +--------
dcmnet/libsrc/dulparse.cc | 100 +++++++++++++-----
dcmnet/libsrc/dulpres.cc | 2 +-
dcmnet/libsrc/helpers.cc | 71 +++++++++++++
13 files changed, 201 insertions(+), 106 deletions(-)
rename dcmnet/{libsrc => include/dcmtk/dcmnet}/dulstruc.h (98%)
create mode 100644 dcmnet/include/dcmtk/dcmnet/helpers.h
create mode 100644 dcmnet/libsrc/helpers.cc
diff --git a/dcmnet/libsrc/dulstruc.h b/dcmnet/include/dcmtk/dcmnet/dulstruc.h
similarity index 98%
rename from dcmnet/libsrc/dulstruc.h
rename to dcmnet/include/dcmtk/dcmnet/dulstruc.h
index 22da6ece1..6ac9a8f5d 100644
--- a/dcmnet/libsrc/dulstruc.h
+++ b/dcmnet/include/dcmtk/dcmnet/dulstruc.h
@@ -71,6 +71,11 @@
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/dcmnet/extneg.h"
#include "dcmtk/dcmnet/dcuserid.h"
+#include "dcmtk/dcmnet/dicom.h"
+#include "dcmtk/dcmnet/dntypes.h"
+#include "dcmtk/dcmnet/dul.h"
+#include "dcmtk/dcmnet/lst.h"
+
class DcmTransportConnection;
class DcmTransportLayer;
@@ -290,6 +295,9 @@ typedef struct dul_datapdu {
DUL_PRESENTATIONDATAVALUE presentationDataValue;
} DUL_DATAPDU;
+
+
+
#define DUL_PROTOCOL (unsigned short) 0x01
#define DUL_TYPEAPPLICATIONCONTEXT (unsigned char)0x10
diff --git a/dcmnet/include/dcmtk/dcmnet/helpers.h b/dcmnet/include/dcmtk/dcmnet/helpers.h
new file mode 100644
index 000000000..7d7e382be
--- /dev/null
+++ b/dcmnet/include/dcmtk/dcmnet/helpers.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright (C) 2021, OFFIS e.V.
+ * All rights reserved. See COPYRIGHT file for details.
+ *
+ * This software and supporting documentation were partly developed by
+ *
+ * OFFIS e.V.
+ * R&D Division Health
+ * Escherweg 2
+ * D-26121 Oldenburg, Germany
+ *
+ *
+ * Module: dcmnet
+ *
+ * Author: Michael Onken
+ *
+ * Purpose: Collection of helper functions
+ *
+ */
+
+#ifndef DCMHET_HELPERS_H
+#define DCMHET_HELPERS_H
+
+#include "dcmtk/ofstd/ofcond.h"
+#include "dcmtk/dcmnet/dulstruc.h"
+
+struct T_ASC_Parameters;
+class LST_HEAD;
+
+
+void
+destroyPresentationContextList(LST_HEAD ** l);
+
+void
+destroyUserInformationLists(DUL_USERINFO * userInfo);
+
+#endif
diff --git a/dcmnet/libsrc/CMakeLists.txt b/dcmnet/libsrc/CMakeLists.txt
index ed902ddc1..ee39d0f14 100644
--- a/dcmnet/libsrc/CMakeLists.txt
+++ b/dcmnet/libsrc/CMakeLists.txt
@@ -1,5 +1,5 @@
# create library from source files
-DCMTK_ADD_LIBRARY(dcmnet assoc cond dcasccff dcasccfg dccfenmp dccfpcmp dccfprmp dccfrsmp dccftsmp dccfuidh dcmlayer dcmtrans dcompat dimcancl dimcmd dimdump dimecho dimfind dimget dimmove dimse dimstore diutil dul dulconst dulextra dulfsm dulparse dulpres extneg lst dfindscu dstorscp dstorscu dcuserid scu scp scpthrd scpcfg scppool dwrap)
+DCMTK_ADD_LIBRARY(dcmnet assoc cond dcasccff dcasccfg dccfenmp dccfpcmp dccfprmp dccfrsmp dccftsmp dccfuidh dcmlayer dcmtrans dcompat dimcancl dimcmd dimdump dimecho dimfind dimget dimmove dimse dimstore diutil dul dulconst dulextra dulfsm dulparse dulpres extneg helpers lst dfindscu dstorscp dstorscu dcuserid scu scp scpthrd scpcfg scppool dwrap)
DCMTK_TARGET_LINK_MODULES(dcmnet ofstd oflog dcmdata)
DCMTK_TARGET_LINK_LIBRARIES(dcmnet ${WRAP_LIBS})
diff --git a/dcmnet/libsrc/Makefile.in b/dcmnet/libsrc/Makefile.in
index 66d8c527b..d767bea35 100644
--- a/dcmnet/libsrc/Makefile.in
+++ b/dcmnet/libsrc/Makefile.in
@@ -25,7 +25,7 @@ objs = assoc.o cond.o dcompat.o dimcancl.o dimcmd.o dimdump.o dimecho.o \
dulfsm.o dulparse.o dulpres.o dul.o lst.o extneg.o dimget.o dcmlayer.o \
dcmtrans.o dcasccfg.o dcasccff.o dccfuidh.o dccftsmp.o dccfpcmp.o \
dccfrsmp.o dccfenmp.o dccfprmp.o dfindscu.o dstorscp.o dstorscu.o \
- dcuserid.o scu.o scp.o scpcfg.o scpthrd.o scppool.o dwrap.o
+ dcuserid.o helper.o scu.o scp.o scpcfg.o scpthrd.o scppool.o dwrap.o
library = libdcmnet.$(LIBEXT)
diff --git a/dcmnet/libsrc/assoc.cc b/dcmnet/libsrc/assoc.cc
index 6dbe4ef4d..a97f10699 100644
--- a/dcmnet/libsrc/assoc.cc
+++ b/dcmnet/libsrc/assoc.cc
@@ -125,6 +125,7 @@
#include "dcmtk/ofstd/ofconsol.h"
#include "dcmtk/ofstd/ofstd.h"
#include "dcmtk/dcmnet/dcmtrans.h"
+#include "dcmtk/dcmnet/helpers.h"
/*
** Constant Definitions
@@ -343,25 +344,6 @@ ASC_createAssociationParameters(T_ASC_Parameters ** params,
return EC_Normal;
}
-static void
-destroyPresentationContextList(LST_HEAD ** lst)
-{
- DUL_PRESENTATIONCONTEXT *pc;
- DUL_TRANSFERSYNTAX *ts;
-
- if ((lst == NULL) || (*lst == NULL))
- return;
- while ((pc = (DUL_PRESENTATIONCONTEXT*) LST_Dequeue(lst)) != NULL) {
- if (pc->proposedTransferSyntax != NULL) {
- while ((ts = (DUL_TRANSFERSYNTAX*) LST_Dequeue(&pc->proposedTransferSyntax)) != NULL) {
- free(ts);
- }
- LST_Destroy(&pc->proposedTransferSyntax);
- }
- free(pc);
- }
- LST_Destroy(lst);
-}
OFCondition
ASC_destroyAssociationParameters(T_ASC_Parameters ** params)
@@ -1706,8 +1688,7 @@ ASC_destroyAssociation(T_ASC_Association ** association)
}
if ((*association)->params != NULL) {
- cond = ASC_destroyAssociationParameters(&(*association)->params);
- if (cond.bad()) return cond;
+ ASC_destroyAssociationParameters(&(*association)->params);
}
if ((*association)->sendPDVBuffer != NULL)
diff --git a/dcmnet/libsrc/dcuserid.cc b/dcmnet/libsrc/dcuserid.cc
index 6a2d72a20..f1530fe79 100644
--- a/dcmnet/libsrc/dcuserid.cc
+++ b/dcmnet/libsrc/dcuserid.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright (C) 1997-2018, OFFIS e.V.
+ * Copyright (C) 1997-2021, OFFIS e.V.
* All rights reserved. See COPYRIGHT file for details.
*
* This software and supporting documentation were developed by
@@ -23,7 +23,7 @@
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/dcmnet/dcuserid.h"
#include "dcmtk/dcmnet/dul.h"
-#include "dulstruc.h"
+#include "dcmtk/dcmnet/dulstruc.h"
/* ************************************************************************* */
/* Implementation of class UserIdentityNegotiationSubItem */
diff --git a/dcmnet/libsrc/dul.cc b/dcmnet/libsrc/dul.cc
index b8e9cc044..38a8d730e 100644
--- a/dcmnet/libsrc/dul.cc
+++ b/dcmnet/libsrc/dul.cc
@@ -142,7 +142,7 @@ END_EXTERN_C
#include "dcmtk/ofstd/ofstd.h"
#include "dcmtk/dcmnet/dul.h"
-#include "dulstruc.h"
+#include "dcmtk/dcmnet/dulstruc.h"
#include "dulpriv.h"
#include "dulfsm.h"
#include "dcmtk/dcmnet/dcmtrans.h"
diff --git a/dcmnet/libsrc/dulconst.cc b/dcmnet/libsrc/dulconst.cc
index c0643c2bc..13738e8ea 100644
--- a/dcmnet/libsrc/dulconst.cc
+++ b/dcmnet/libsrc/dulconst.cc
@@ -77,7 +77,7 @@
#include "dcmtk/dcmnet/diutil.h"
#include "dcmtk/dcmnet/lst.h"
#include "dcmtk/dcmnet/dul.h"
-#include "dulstruc.h"
+#include "dcmtk/dcmnet/dulstruc.h"
#include "dulpriv.h"
#include "dcmtk/ofstd/ofconsol.h"
diff --git a/dcmnet/libsrc/dulextra.cc b/dcmnet/libsrc/dulextra.cc
index 9845f3e4c..bec14fc2b 100644
--- a/dcmnet/libsrc/dulextra.cc
+++ b/dcmnet/libsrc/dulextra.cc
@@ -102,7 +102,7 @@
#include "dcmtk/dcmnet/lst.h"
#include "dcmtk/dcmnet/cond.h"
#include "dcmtk/dcmnet/dul.h"
-#include "dulstruc.h"
+#include "dcmtk/dcmnet/dulstruc.h"
#include "dulpriv.h"
#include "dcmtk/dcmnet/dcmtrans.h"
#include "dcmtk/dcmnet/diutil.h"
diff --git a/dcmnet/libsrc/dulfsm.cc b/dcmnet/libsrc/dulfsm.cc
index 91dcc7fcb..9bbe3462a 100644
--- a/dcmnet/libsrc/dulfsm.cc
+++ b/dcmnet/libsrc/dulfsm.cc
@@ -113,7 +113,7 @@ END_EXTERN_C
#include "dcmtk/dcmnet/lst.h"
#include "dcmtk/dcmnet/cond.h"
#include "dcmtk/dcmnet/dul.h"
-#include "dulstruc.h"
+#include "dcmtk/dcmnet/dulstruc.h"
#include "dulpriv.h"
#include "dulfsm.h"
#include "dcmtk/ofstd/ofbmanip.h"
@@ -122,6 +122,7 @@ END_EXTERN_C
#include "dcmtk/dcmnet/dcmtrans.h"
#include "dcmtk/dcmnet/dcmlayer.h"
#include "dcmtk/dcmnet/diutil.h"
+#include "dcmtk/dcmnet/helpers.h"
#include "dcmtk/ofstd/ofsockad.h" /* for class OFSockAddr */
/* At least Solaris doesn't define this */
@@ -310,9 +311,6 @@ findPresentationCtx(LST_HEAD ** lst, DUL_PRESENTATIONCONTEXTID contextID);
PRV_SCUSCPROLE *
findSCUSCPRole(LST_HEAD ** lst, char *abstractSyntax);
-void destroyPresentationContextList(LST_HEAD ** l);
-void destroyUserInformationLists(DUL_USERINFO * userInfo);
-
static volatile FSM_Event_Description Event_Table[] = {
{A_ASSOCIATE_REQ_LOCAL_USER, "A-ASSOCIATE request (local user)"},
{TRANS_CONN_CONFIRM_LOCAL_USER, "Transport conn confirmation (local)"},
@@ -3988,48 +3986,3 @@ findSCUSCPRole(LST_HEAD ** lst, char *abstractSyntax)
}
return NULL;
}
-
-void
-destroyPresentationContextList(LST_HEAD ** l)
-{
- PRV_PRESENTATIONCONTEXTITEM
- * prvCtx;
- DUL_SUBITEM
- * subItem;
-
- if (*l == NULL)
- return;
-
- prvCtx = (PRV_PRESENTATIONCONTEXTITEM*)LST_Dequeue(l);
- while (prvCtx != NULL) {
- subItem = (DUL_SUBITEM*)LST_Dequeue(&prvCtx->transferSyntaxList);
- while (subItem != NULL) {
- free(subItem);
- subItem = (DUL_SUBITEM*)LST_Dequeue(&prvCtx->transferSyntaxList);
- }
- LST_Destroy(&prvCtx->transferSyntaxList);
- free(prvCtx);
- prvCtx = (PRV_PRESENTATIONCONTEXTITEM*)LST_Dequeue(l);
- }
- LST_Destroy(l);
-}
-
-void
-destroyUserInformationLists(DUL_USERINFO * userInfo)
-{
- PRV_SCUSCPROLE
- * role;
-
- role = (PRV_SCUSCPROLE*)LST_Dequeue(&userInfo->SCUSCPRoleList);
- while (role != NULL) {
- free(role);
- role = (PRV_SCUSCPROLE*)LST_Dequeue(&userInfo->SCUSCPRoleList);
- }
- LST_Destroy(&userInfo->SCUSCPRoleList);
-
- /* extended negotiation */
- delete userInfo->extNegList; userInfo->extNegList = NULL;
-
- /* user identity negotiation */
- delete userInfo->usrIdent; userInfo->usrIdent = NULL;
-}
diff --git a/dcmnet/libsrc/dulparse.cc b/dcmnet/libsrc/dulparse.cc
index 0a84f3850..decd60dc5 100644
--- a/dcmnet/libsrc/dulparse.cc
+++ b/dcmnet/libsrc/dulparse.cc
@@ -75,7 +75,8 @@
#include "dcmtk/dcmnet/lst.h"
#include "dcmtk/dcmnet/dul.h"
#include "dcmtk/dcmnet/diutil.h"
-#include "dulstruc.h"
+#include "dcmtk/dcmnet/dulstruc.h"
+#include "dcmtk/dcmnet/helpers.h"
#include "dulpriv.h"
#include "dcmtk/ofstd/ofconsol.h"
@@ -147,9 +148,6 @@ parseAssociate(unsigned char *buf, unsigned long pduLength,
* context;
(void) memset(assoc, 0, sizeof(*assoc));
- if ((assoc->presentationContextList = LST_Create()) == NULL) return EC_MemoryExhausted;
- if ((assoc->userInfo.SCUSCPRoleList = LST_Create()) == NULL) return EC_MemoryExhausted;
-
// Check if the PDU actually is long enough for the fields we read
if (pduLength < 2 + 2 + 16 + 16 + 32)
return makeLengthError("associate PDU", pduLength, 2 + 2 + 16 + 16 + 32);
@@ -210,6 +208,8 @@ parseAssociate(unsigned char *buf, unsigned long pduLength,
<< "Called AP Title: " << assoc->calledAPTitle << OFendl
<< "Calling AP Title: " << assoc->callingAPTitle);
}
+ if ((assoc->presentationContextList = LST_Create()) == NULL) return EC_MemoryExhausted;
+ if ((assoc->userInfo.SCUSCPRoleList = LST_Create()) == NULL) return EC_MemoryExhausted;
while ((cond.good()) && (pduLength > 0))
{
type = *buf;
@@ -224,44 +224,80 @@ parseAssociate(unsigned char *buf, unsigned long pduLength,
{
buf += itemLength;
if (!OFStandard::safeSubtract(pduLength, itemLength, pduLength))
- return makeUnderflowError("Application Context item", pduLength, itemLength);
- DCMNET_TRACE("Successfully parsed Application Context");
+ {
+ cond = makeUnderflowError("Application Context item", pduLength, itemLength);
+ }
+ else
+ {
+ DCMNET_TRACE("Successfully parsed Application Context");
+ }
}
break;
case DUL_TYPEPRESENTATIONCONTEXTRQ:
case DUL_TYPEPRESENTATIONCONTEXTAC:
context = (PRV_PRESENTATIONCONTEXTITEM*)malloc(sizeof(PRV_PRESENTATIONCONTEXTITEM));
- if (context == NULL) return EC_MemoryExhausted;
- (void) memset(context, 0, sizeof(*context));
- cond = parsePresentationContext(type, context, buf, &itemLength, pduLength);
- if (cond.bad()) return cond;
- buf += itemLength;
- if (!OFStandard::safeSubtract(pduLength, itemLength, pduLength))
- return makeUnderflowError("Presentation Context item", pduLength, itemLength);
- LST_Enqueue(&assoc->presentationContextList, (LST_NODE*)context);
- DCMNET_TRACE("Successfully parsed Presentation Context");
+ if (context != NULL)
+ {
+ (void) memset(context, 0, sizeof(*context));
+ cond = parsePresentationContext(type, context, buf, &itemLength, pduLength);
+ if (cond.bad())
+ {
+ free(context);
+ }
+ else
+ {
+ buf += itemLength;
+ if (!OFStandard::safeSubtract(pduLength, itemLength, pduLength))
+ {
+ cond = makeUnderflowError("Presentation Context item", pduLength, itemLength);
+ }
+ else
+ {
+ LST_Enqueue(&assoc->presentationContextList, (LST_NODE*)context);
+ DCMNET_TRACE("Successfully parsed Presentation Context");
+ }
+ }
+ }
+ else
+ {
+ cond = EC_MemoryExhausted;
+ }
break;
case DUL_TYPEUSERINFO:
// parse user info, which can contain several sub-items like User
// Identity Negotiation or SOP Class Extended Negotiation
cond = parseUserInfo(&assoc->userInfo, buf, &itemLength, assoc->type, pduLength);
- if (cond.bad())
- return cond;
- buf += itemLength;
- if (!OFStandard::safeSubtract(pduLength, itemLength, pduLength))
- return makeUnderflowError("User Information item", pduLength, itemLength);
- DCMNET_TRACE("Successfully parsed User Information");
+ if (cond.good())
+ {
+ buf += itemLength;
+ if (!OFStandard::safeSubtract(pduLength, itemLength, pduLength))
+ {
+ cond = makeUnderflowError("User Information item", pduLength, itemLength);
+ }
+ else
+ {
+ DCMNET_TRACE("Successfully parsed User Information");
+ }
+ }
break;
default:
cond = parseDummy(buf, &itemLength, pduLength);
- if (cond.bad())
- return cond;
- buf += itemLength;
- if (!OFStandard::safeSubtract(pduLength, itemLength, pduLength))
- return makeUnderflowError("unknown item type", pduLength, itemLength);
+ if (cond.good())
+ {
+ buf += itemLength;
+ if (!OFStandard::safeSubtract(pduLength, itemLength, pduLength))
+ {
+ cond = makeUnderflowError("unknown item type", pduLength, itemLength);
+ }
+ }
break;
}
}
+ if (cond.bad())
+ {
+ destroyPresentationContextList(&assoc->presentationContextList);
+ destroyUserInformationLists(&assoc->userInfo);
+ }
return cond;
}
@@ -409,7 +445,11 @@ parsePresentationContext(unsigned char type,
subItem = (DUL_SUBITEM*)malloc(sizeof(DUL_SUBITEM));
if (subItem == NULL) return EC_MemoryExhausted;
cond = parseSubItem(subItem, buf, &length, presentationLength);
- if (cond.bad()) return cond;
+ if (cond.bad())
+ {
+ free(subItem);
+ return cond;
+ }
LST_Enqueue(&context->transferSyntaxList, (LST_NODE*)subItem);
buf += length;
if (!OFStandard::safeSubtract(presentationLength, length, presentationLength))
@@ -530,7 +570,11 @@ parseUserInfo(DUL_USERINFO * userInfo,
role = (PRV_SCUSCPROLE*)malloc(sizeof(PRV_SCUSCPROLE));
if (role == NULL) return EC_MemoryExhausted;
cond = parseSCUSCPRole(role, buf, &length, userLength);
- if (cond.bad()) return cond;
+ if (cond.bad())
+ {
+ free(role);
+ return cond;
+ }
LST_Enqueue(&userInfo->SCUSCPRoleList, (LST_NODE*)role);
buf += length;
if (!OFStandard::safeSubtract(userLength, OFstatic_cast(short unsigned int, length), userLength))
diff --git a/dcmnet/libsrc/dulpres.cc b/dcmnet/libsrc/dulpres.cc
index a0b8d618c..77be86c24 100644
--- a/dcmnet/libsrc/dulpres.cc
+++ b/dcmnet/libsrc/dulpres.cc
@@ -74,7 +74,7 @@
#include "dcmtk/dcmnet/cond.h"
#include "dcmtk/dcmnet/lst.h"
#include "dcmtk/dcmnet/dul.h"
-#include "dulstruc.h"
+#include "dcmtk/dcmnet/dulstruc.h"
#include "dulpriv.h"
#include "dulfsm.h"
diff --git a/dcmnet/libsrc/helpers.cc b/dcmnet/libsrc/helpers.cc
new file mode 100644
index 000000000..9cd20cefc
--- /dev/null
+++ b/dcmnet/libsrc/helpers.cc
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright (C) 2021, OFFIS e.V.
+ * All rights reserved. See COPYRIGHT file for details.
+ *
+ * This software and supporting documentation were partly developed by
+ *
+ * OFFIS e.V.
+ * R&D Division Health
+ * Escherweg 2
+ * D-26121 Oldenburg, Germany
+ *
+ *
+ * Module: dcmnet
+ *
+ * Author: Michael Onken
+ *
+ * Purpose: Collection of helper functions
+ *
+ */
+
+#include "dcmtk/dcmnet/helpers.h"
+#include "dcmtk/dcmnet/lst.h"
+#include "dcmtk/dcmnet/assoc.h"
+#include "dcmtk/dcmnet/dulstruc.h"
+
+
+void
+destroyPresentationContextList(LST_HEAD ** l)
+{
+ PRV_PRESENTATIONCONTEXTITEM
+ * prvCtx;
+ DUL_SUBITEM
+ * subItem;
+
+ if (*l == NULL)
+ return;
+
+ prvCtx = (PRV_PRESENTATIONCONTEXTITEM*)LST_Dequeue(l);
+ while (prvCtx != NULL) {
+ subItem = (DUL_SUBITEM*)LST_Dequeue(&prvCtx->transferSyntaxList);
+ while (subItem != NULL) {
+ free(subItem);
+ subItem = (DUL_SUBITEM*)LST_Dequeue(&prvCtx->transferSyntaxList);
+ }
+ LST_Destroy(&prvCtx->transferSyntaxList);
+ free(prvCtx);
+ prvCtx = (PRV_PRESENTATIONCONTEXTITEM*)LST_Dequeue(l);
+ }
+ LST_Destroy(l);
+}
+
+void
+destroyUserInformationLists(DUL_USERINFO * userInfo)
+{
+ PRV_SCUSCPROLE
+ * role;
+
+ role = (PRV_SCUSCPROLE*)LST_Dequeue(&userInfo->SCUSCPRoleList);
+ while (role != NULL) {
+ free(role);
+ role = (PRV_SCUSCPROLE*)LST_Dequeue(&userInfo->SCUSCPRoleList);
+ }
+ LST_Destroy(&userInfo->SCUSCPRoleList);
+
+ /* extended negotiation */
+ delete userInfo->extNegList; userInfo->extNegList = NULL;
+
+ /* user identity negotiation */
+ delete userInfo->usrIdent; userInfo->usrIdent = NULL;
+}
--
2.39.2