⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sess_iattr.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
	assert( isWritePtr( attributeListCursorPtr, sizeof( ATTRIBUTE_LIST * ) ) );
	assert( sessionInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP || \
			sessionInfoType == CRYPT_ATTRIBUTE_CURRENT || \
			sessionInfoType == CRYPT_ATTRIBUTE_CURRENT_INSTANCE );
	assert( position <= CRYPT_CURSOR_FIRST && \
			position >= CRYPT_CURSOR_LAST );

	/* If it's an absolute positioning code, pre-set the attribute cursor if 
	   required */
	if( position == CRYPT_CURSOR_FIRST || position == CRYPT_CURSOR_LAST )
		{
		if( attributeListHead == NULL )
			return( CRYPT_ERROR_NOTFOUND );

		/* If it's an absolute attribute positioning code, reset the 
		   attribute cursor to the start of the list before we try to move 
		   it, and if it's an attribute positioning code, initialise the 
		   attribute cursor if necessary */
		if( sessionInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP || \
			attributeListPtr == NULL )
			{
			attributeListPtr = attributeListHead;
			resetVirtualCursor( attributeListPtr );
			}

		/* If there are no attributes present, return the appropriate error 
		   code */
		if( attributeListPtr == NULL )
			return( ( position == CRYPT_CURSOR_FIRST || \
					  position == CRYPT_CURSOR_LAST ) ? \
					 CRYPT_ERROR_NOTFOUND : CRYPT_ERROR_NOTINITED );
		}
	else
		/* It's a relative positioning code, return a not-inited error 
		   rather than a not-found error if the cursor isn't set since there 
		   may be attributes present but the cursor hasn't been initialised 
		   yet by selecting the first or last absolute attribute */
		if( attributeListPtr == NULL )
			return( CRYPT_ERROR_NOTINITED );

	/* Move the cursor */
	attributeListPtr = ( ATTRIBUTE_LIST * ) \
					   attributeMoveCursor( attributeListPtr, getAttrFunction, 
											sessionInfoType, position );
	if( attributeListPtr == NULL )
		return( CRYPT_ERROR_NOTFOUND );
	*attributeListCursorPtr = attributeListPtr;
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*								Find an Attribute							*
*																			*
****************************************************************************/

/* Find a session attribute by type */

const ATTRIBUTE_LIST *findSessionInfo( const ATTRIBUTE_LIST *attributeListPtr,
								const CRYPT_ATTRIBUTE_TYPE attributeID )
	{
	assert( attributeListPtr == NULL || \
			isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );

	return( attributeFind( attributeListPtr, getAttrFunction, 
						   attributeID, CRYPT_ATTRIBUTE_NONE ) );
	}

/* Find a session attribute by type and content */

const ATTRIBUTE_LIST *findSessionInfoEx( const ATTRIBUTE_LIST *attributeListPtr,
								const CRYPT_ATTRIBUTE_TYPE attributeID,
								const void *value, const int valueLength )
	{
	const ATTRIBUTE_LIST *attributeListCursor;
	int iterationCount = 0;

	assert( attributeListPtr == NULL || \
			isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );

	/* Find the first attribute of this type */
	attributeListCursor = attributeFind( attributeListPtr, getAttrFunction, 
										 attributeID, CRYPT_ATTRIBUTE_NONE );
	if( attributeListCursor == NULL )
		return( NULL );

	/* Walk down the rest of the list looking for an attribute entry whose 
	   contents match the requested contents.  Unfortunately we can't use 
	   attributeFindNextInstance() to help us because that finds the next 
	   instance of the current attribute in an attribute group, not the next 
	   instance in an interleaved set of attributes */
	while( attributeListCursor != NULL && \
		   iterationCount++ < FAILSAFE_ITERATIONS_MAX )
		{
		if( attributeListCursor->attributeID == attributeID && \
			attributeListCursor->valueLength == valueLength && \
			!memcmp( attributeListCursor->value, value, valueLength ) )
			break;
		attributeListCursor = attributeListCursor->next;
		}
	if( iterationCount >= FAILSAFE_ITERATIONS_MAX )
		retIntError_Null();

	return( attributeListCursor );
	}

/****************************************************************************
*																			*
*								Add an Attribute							*
*																			*
****************************************************************************/

/* Add a session attribute.  There are two versions of this function, the
   standard version and an extended version that allows the caller to 
   specify an access function to access session subtype-specific internal
   attributes when the data being added is structured session-type-specific
   data, and a set of ATTR_FLAG_xxx flags to provide precise control over
   the attribute handling */

static int addInfo( ATTRIBUTE_LIST **listHeadPtr,
					const CRYPT_ATTRIBUTE_TYPE groupID,
					const CRYPT_ATTRIBUTE_TYPE attributeID,
					const void *data, const int dataLength, 
					const int dataMaxLength, 
					const ATTRACCESSFUNCTION accessFunction, 
					const int flags )
	{
	ATTRIBUTE_LIST *newElement, *insertPoint = NULL;

	assert( isWritePtr( listHeadPtr, sizeof( ATTRIBUTE_LIST * ) ) );
	assert( groupID > CRYPT_SESSINFO_FIRST && \
			groupID < CRYPT_SESSINFO_LAST );
	assert( attributeID > CRYPT_SESSINFO_FIRST && \
			attributeID < CRYPT_SESSINFO_LAST );
	assert( ( data == NULL ) || \
			( isReadPtr( data, dataLength ) && \
			  dataLength <= dataMaxLength ) );
	assert( dataMaxLength >= 0 );
	assert( !( flags & ATTR_FLAG_COMPOSITE ) || \
			accessFunction != NULL );

	/* Find the correct insertion point and make sure that the attribute 
	   isn't already present */
	if( *listHeadPtr != NULL )
		{
		ATTRIBUTE_LIST *prevElement = NULL;
		int iterationCount = 0;

		for( insertPoint = *listHeadPtr; 
			 insertPoint != NULL && \
				iterationCount++ < FAILSAFE_ITERATIONS_MAX;
			 insertPoint = insertPoint->next )
			{
			/* If this is a non-multivalued attribute, make sure that it
			   isn't already present */
			if( !( flags & ATTR_FLAG_MULTIVALUED ) && \
				insertPoint->attributeID == attributeID )
				return( CRYPT_ERROR_INITED );

			prevElement = insertPoint;
			}
		if( iterationCount >= FAILSAFE_ITERATIONS_MAX )
			retIntError();
		insertPoint = prevElement;
		}

	/* Allocate memory for the new element and copy the information across.  
	   The data is stored in storage ... storage + dataLength, with storage
	   reserved up to dataMaxLength (if it's greater than dataLength) to
	   allow the contents to be replaced with a new fixed-length value  */
	if( ( newElement = ( ATTRIBUTE_LIST * ) \
					   clAlloc( "addSessionAttribute", sizeof( ATTRIBUTE_LIST ) + \
													   dataMaxLength ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	initVarStruct( newElement, ATTRIBUTE_LIST, dataMaxLength );
	newElement->groupID = groupID;
	newElement->attributeID = attributeID;
	newElement->accessFunction = accessFunction;
	newElement->flags = flags;
	if( data == NULL )
		newElement->intValue = dataLength;
	else
		{
		assert( isReadPtr( data, dataLength ) );

		memcpy( newElement->value, data, dataLength );
		newElement->valueLength = dataLength;
		}
	insertDoubleListElement( listHeadPtr, insertPoint, newElement );

	return( CRYPT_OK );
	}

int addSessionInfo( ATTRIBUTE_LIST **listHeadPtr,
					const CRYPT_ATTRIBUTE_TYPE attributeID,
					const void *data, const int dataLength )
	{
	/* Pre-3.3 kludge: Set the groupID to the attributeID since groups 
	   aren't defined yet */
	return( addInfo( listHeadPtr, attributeID, attributeID, data, 
					 dataLength, dataLength, NULL, ATTR_FLAG_NONE ) );
	}

int addSessionInfoEx( ATTRIBUTE_LIST **listHeadPtr,
					  const CRYPT_ATTRIBUTE_TYPE attributeID,
					  const void *data, const int dataLength, 
					  const int flags )
	{
	/* Pre-3.3 kludge: Set the groupID to the attributeID since groups 
	   aren't defined yet */
	return( addInfo( listHeadPtr, attributeID, attributeID, data, 
					 dataLength, dataLength, NULL, flags ) );
	}

int addSessionInfoComposite( ATTRIBUTE_LIST **listHeadPtr,
							 const CRYPT_ATTRIBUTE_TYPE attributeID,
							 const ATTRACCESSFUNCTION accessFunction, 
							 const void *data, const int dataLength,
							 const int flags )
	{
	/* For composite attributes the groupID is the attributeID, with the
	   actual attributeID being returned by the accessFunction */
	return( addInfo( listHeadPtr, attributeID, attributeID, data, 
					 dataLength, dataLength, accessFunction, flags ) );
	}

/* Update a session attribute, either by replacing an existing entry if it
   already exists or by adding a new entry */

int updateSessionInfo( ATTRIBUTE_LIST **listHeadPtr,
					   const CRYPT_ATTRIBUTE_TYPE attributeID,
					   const void *data, const int dataLength,
					   const int dataMaxLength, const int flags )
	{
	ATTRIBUTE_LIST *attributeListPtr = *listHeadPtr;

	assert( !( flags & ATTR_FLAG_MULTIVALUED ) );

	/* Find the first attribute of this type */
	attributeListPtr = attributeFind( attributeListPtr, getAttrFunction, 
									  attributeID, CRYPT_ATTRIBUTE_NONE );

	/* If the attribute is already present, update the value */
	if( attributeListPtr != NULL )
		{
		assert( attributeListPtr->attributeID == attributeID );
		assert( ( attributeListPtr->valueLength == 0 && \
				  !memcmp( attributeListPtr->value, \
						   "\x00\x00\x00\x00", 4 ) ) || \
				attributeListPtr->valueLength > 0 );
		assert( isReadPtr( data, dataLength ) && \
				dataLength <= dataMaxLength );

		zeroise( attributeListPtr->value, attributeListPtr->valueLength );
		memcpy( attributeListPtr->value, data, dataLength );
		attributeListPtr->valueLength = dataLength;
		return( CRYPT_OK );
		}

	/* The attribute isn't already present, it's a straight add */
	return( addInfo( listHeadPtr, attributeID, attributeID, data, 
					 dataLength, dataMaxLength, NULL, flags ) );
	}

/****************************************************************************
*																			*
*								Delete an Attribute							*
*																			*
****************************************************************************/

/* Delete a complete set of session attributes */

void deleteSessionInfo( ATTRIBUTE_LIST **attributeListHead,
						ATTRIBUTE_LIST **attributeListCurrent,
						ATTRIBUTE_LIST *attributeListPtr )
	{
	assert( isWritePtr( attributeListHead, sizeof( ATTRIBUTE_LIST * ) ) );
	assert( isWritePtr( attributeListCurrent, sizeof( ATTRIBUTE_LIST * ) ) );
	assert( isWritePtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );

	/* If we're about to delete the attribute that's pointed to by the 
	   current-attribute pointer, advance it to the next attribute.  If 
	   there's no next attribute, move it to the previous attribute.  This 
	   behaviour is the most logically consistent, it means that we can do 
	   things like deleting an entire attribute list by repeatedly deleting 
	   a single attribute */
	if( *attributeListCurrent == attributeListPtr )
		*attributeListCurrent = ( attributeListPtr->next != NULL ) ? \
								attributeListPtr->next : \
								attributeListPtr->prev;

	/* Remove the item from the list */
	deleteDoubleListElement( attributeListHead, attributeListPtr );

	/* Clear all data in the list item and free the memory */
	endVarStruct( attributeListPtr, ATTRIBUTE_LIST );
	clFree( "deleteSessionInfo", attributeListPtr );
	}

void deleteSessionInfoAll( ATTRIBUTE_LIST **attributeListHead,
						   ATTRIBUTE_LIST **attributeListCurrent )
	{
	ATTRIBUTE_LIST *attributeListCursor = *attributeListHead;
	int iterationCount = 0;

	assert( isWritePtr( attributeListHead, sizeof( ATTRIBUTE_LIST * ) ) );
	assert( isWritePtr( attributeListCurrent, sizeof( ATTRIBUTE_LIST * ) ) );

	/* If the list was empty, return now */
	if( attributeListCursor == NULL )
		{
		assert( *attributeListCurrent == NULL );
		return;
		}

	/* Destroy any remaining list items */
	while( attributeListCursor != NULL && \
		   iterationCount++ < FAILSAFE_ITERATIONS_MAX )
		{
		ATTRIBUTE_LIST *itemToFree = attributeListCursor;

		attributeListCursor = attributeListCursor->next;
		deleteSessionInfo( attributeListHead, attributeListCurrent, 
						   itemToFree );
		}
	if( iterationCount >= FAILSAFE_ITERATIONS_MAX )
		retIntError_Void();
	*attributeListCurrent = NULL;

	assert( *attributeListHead == NULL );
	}

#endif /* USE_SESSIONS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -