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

📄 sess_iattr.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*			cryptlib Session-specific Attribute Support Routines			*
*					  Copyright Peter Gutmann 1998-2005						*
*																			*
****************************************************************************/

#if defined( INC_ALL )
  #include "crypt.h"
  #include "session.h"
#else
  #include "crypt.h"
  #include "session/session.h"
#endif /* Compiler-specific includes */

#ifdef USE_SESSIONS

/****************************************************************************
*																			*
*								Utility Functions							*
*																			*
****************************************************************************/

/* Reset the internal virtual cursor in a attribute-list item after we've 
   moved the attribute cursor */

#define resetVirtualCursor( attributeListPtr ) \
		if( attributeListPtr != NULL ) \
			attributeListPtr->flags |= ATTR_FLAG_CURSORMOVED

/* Helper function used to access internal attributes within an attribute 
   group */

#if 0	/* Currently unused, will be enabled in 3.3 with the move to 
		   composite attributes for host/client info */

static int accessFunction( ATTRIBUTE_LIST *attributeListPtr,
						   const ATTR_TYPE attrGetType )
	{
	static const CRYPT_ATTRIBUTE_TYPE attributeOrderList[] = {
				CRYPT_SESSINFO_NAME, CRYPT_SESSINFO_PASSWORD,
				CRYPT_SESSINFO_KEY, CRYPT_ATTRIBUTE_NONE, 
				CRYPT_ATTRIBUTE_NONE };
	USER_INFO *userInfoPtr = attributeListPtr->value;
	CRYPT_ATTRIBUTE_TYPE attributeID = userInfoPtr->cursorPos;
	BOOLEAN doContinue;
	int iterationCount = 0;

	/* If we've just moved the cursor onto this attribute, reset the 
	   position to the first internal attribute */
	if( attributeListPtr->flags & ATTR_FLAG_CURSORMOVED )
		{
		attributeID = userInfoPtr->cursorPos = \
						CRYPT_ENVINFO_SIGNATURE_RESULT;
		attributeListPtr->flags &= ~ATTR_FLAG_CURSORMOVED;
		}

	/* If it's an info fetch, return the currently-selected attribute */
	if( attrGetType == ATTR_NONE )
		return( attributeID );

	do
		{
		int i;

		/* Find the position of the current sub-attribute in the attribute 
		   order list and use that to get its successor/predecessor sub-
		   attribute */
		for( i = 0; 
			 attributeOrderList[ i ] != attributeID && \
				attributeOrderList[ i ] != CRYPT_ATTRIBUTE_NONE && \
				i < FAILSAFE_ARRAYSIZE( attributeOrderList, CRYPT_ATTRIBUTE_TYPE ); 
			 i++ );
		if( i >= FAILSAFE_ARRAYSIZE( attributeOrderList, CRYPT_ATTRIBUTE_TYPE ) )
			retIntError_False();
		if( attributeOrderList[ i ] == CRYPT_ATTRIBUTE_NONE )
			attributeID = CRYPT_ATTRIBUTE_NONE;
		else
			if( attrGetType == ATTR_PREV )
				attributeID = ( i < 1 ) ? CRYPT_ATTRIBUTE_NONE : \
										  attributeOrderList[ i - 1 ];
			else
				attributeID = attributeOrderList[ i + 1 ];
		if( attributeID == CRYPT_ATTRIBUTE_NONE )
			/* We've reached the first/last sub-attribute within the current 
			   item/group, tell the caller that there are no more sub-
			   attributes present and they have to move on to the next 
			   group */
			return( FALSE );

		/* Check whether the required sub-attribute is present.  If not, we
		   continue and try the next one */
		doContinue = FALSE;
		switch( attributeID )
			{
			case CRYPT_SESSINFO_NAME:
				break;	/* Always present */
				
			case CRYPT_SESSINFO_PASSWORD:
				if( userInfoPtr->passwordLen <= 0 )
					doContinue = TRUE;
				break;
	
			case CRYPT_SESSINFO_KEY:
				if( userInfoPtr->key == CRYPT_ERROR )
					doContinue = TRUE;
				break;

			default:
				retIntError_Boolean();
			}
		}
	while( doContinue && iterationCount++ < FAILSAFE_ITERATIONS_SMALL );
	if( iterationCount >= FAILSAFE_ITERATIONS_SMALL )
		retIntError_False();
	attributeListPtr->attributeCursorEntry = attributeID;
	
	return( TRUE );
	}
#endif /* 0 */

/* Callback function used to provide external access to attribute list-
   internal fields */

static const void *getAttrFunction( const void *attributePtr, 
									CRYPT_ATTRIBUTE_TYPE *groupID, 
									CRYPT_ATTRIBUTE_TYPE *attributeID, 
									CRYPT_ATTRIBUTE_TYPE *instanceID,
									const ATTR_TYPE attrGetType )
	{
	ATTRIBUTE_LIST *attributeListPtr = ( ATTRIBUTE_LIST * ) attributePtr;
	BOOLEAN subGroupMove;

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

	/* Clear return values */
	if( groupID != NULL )
		*groupID = CRYPT_ATTRIBUTE_NONE;
	if( attributeID != NULL )
		*attributeID = CRYPT_ATTRIBUTE_NONE;
	if( instanceID != NULL )
		*instanceID = CRYPT_ATTRIBUTE_NONE;

	/* Move to the next or previous attribute if required.  This isn't just a
	   case of following the prev/next links because some attribute-list 
	   items contain an entire attribute group, so positioning by attribute 
	   merely changes the current selection within the group (== attribute-
	   list item) rather than moving to the previous/next entry.  Because of 
	   this we have to special-case the code for composite items and allow 
	   virtual positioning within the item */
	if( attributeListPtr == NULL )
		return( NULL );
	subGroupMove = ( attrGetType == ATTR_PREV || \
					 attrGetType == ATTR_NEXT ) && \
				   ( attributeListPtr->flags & ATTR_FLAG_COMPOSITE );
	if( subGroupMove )
		{
		assert( attrGetType == ATTR_NEXT || attrGetType == ATTR_PREV );
		assert( attributeListPtr->flags & ATTR_FLAG_COMPOSITE );
		assert( attributeListPtr->accessFunction != NULL );

		subGroupMove = attributeListPtr->accessFunction( attributeListPtr, 
														 attrGetType );
		}

	/* If we're moving by group, move to the next/previous attribute list
	   item and reset the internal virtual cursor.  Note that we always 
	   advance the cursor to the next/prev attribute, it's up to the calling 
	   code to manage attribute by attribute vs.group by group moves */
	if( !subGroupMove && attrGetType != ATTR_CURRENT )
		{
		attributeListPtr = ( attrGetType == ATTR_PREV ) ? \
						   attributeListPtr->prev : attributeListPtr->next;
		resetVirtualCursor( attributeListPtr );
		}
	if( attributeListPtr == NULL )
		return( NULL );

	/* Return ID information to the caller.  We only return the group ID if
	   we've moved within the attribute group, if we've moved from one group
	   to another we leave it cleared because sessions can contain multiple
	   groups with the same ID, and returning an ID identical to the one from
	   the group that we've moved out of would make it look as if we're still 
	   within the same group.  Note that this relies on the behaviour of the
	   attribute-move functions, which first get the current group using 
	   ATTR_CURRENT and then move to the next or previous using ATTR_NEXT/
	   PREV */
	if( groupID != NULL && ( attrGetType == ATTR_CURRENT || subGroupMove ) )
		*groupID = attributeListPtr->groupID;
	if( attributeID != NULL )
		{
		if( attributeListPtr->flags & ATTR_FLAG_COMPOSITE )
			*attributeID = attributeListPtr->accessFunction( attributeListPtr, 
															 ATTR_NONE );
		else
			*attributeID = attributeListPtr->attributeID;
		}

	return( attributeListPtr );
	}

/* Lock ephemeral attributes so that they can't be deleted any more by
   resetEphemeralAttributes().  This just clears the ephemeral flag so that
   they're treated as normal attributes */

void lockEphemeralAttributes( ATTRIBUTE_LIST *attributeListHead )
	{
	ATTRIBUTE_LIST *attributeListCursor;
	int iterationCount = 0;

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

	/* Clear the ATTR_FLAG_EPHEMERAL flag on all attributes */
	for( attributeListCursor = attributeListHead; 
		 attributeListCursor != NULL && \
			iterationCount++ < FAILSAFE_ITERATIONS_MAX;
		 attributeListCursor = attributeListCursor->next )
		attributeListCursor->flags &= ~ATTR_FLAG_EPHEMERAL;
	if( iterationCount >= FAILSAFE_ITERATIONS_MAX )
		retIntError_Void();
	}

/* Check that a set of attributes is well-formed.  We can perform most of 
   the checking as the attributes are added, but some checks (for example
   whether each username has a corresponding password) aren't possible 
   until all of the attributes are present */

CRYPT_ATTRIBUTE_TYPE checkMissingInfo( const ATTRIBUTE_LIST *attributeListHead,
									   const BOOLEAN isServer )
	{
	const ATTRIBUTE_LIST *attributeListPtr = attributeListHead;

	if( attributeListPtr == NULL )
		return( CRYPT_ATTRIBUTE_NONE );

	/* Make sure that every username attribute is paired up with a 
	   corresponding authentication attribute.  This only applies to 
	   servers, because clients can also use private keys for 
	   authentication, and the presence of a key or password is checked
	   elsewhere */
	if( isServer )
		{
		int iterationCount = 0;

		while( ( attributeListPtr = \
					attributeFind( attributeListPtr, getAttrFunction, 
								   CRYPT_SESSINFO_USERNAME, 
								   CRYPT_ATTRIBUTE_NONE ) ) != NULL && \
				iterationCount++ < FAILSAFE_ITERATIONS_MAX )
			{
			/* Make sure that there's a matching authentication attribute */
			if( ( attributeListPtr = attributeListPtr->next ) == NULL )
				return( CRYPT_SESSINFO_PASSWORD );

			/* The authentication attribute is currently a password, but in
			   future versions could also be a public key used for 
			   authentication */
			if( attributeListPtr->attributeID != CRYPT_SESSINFO_PASSWORD )
				return( CRYPT_SESSINFO_PASSWORD );

			/* Move on to the next attribute */
			attributeListPtr = attributeListPtr->next;
			}
		if( iterationCount >= FAILSAFE_ITERATIONS_MAX )
			retIntError_Ext( CRYPT_SESSINFO_ACTIVE );
		}

	return( CRYPT_ATTRIBUTE_NONE );
	}

/****************************************************************************
*																			*
*					Attribute Cursor Management Routines					*
*																			*
****************************************************************************/

/* Get/set the attribute cursor */

int getSessionAttributeCursor( ATTRIBUTE_LIST *attributeListHead,
							   ATTRIBUTE_LIST *attributeListCursor, 
							   const CRYPT_ATTRIBUTE_TYPE sessionInfoType,
							   int *valuePtr )
	{
	BOOLEAN initAttributeList = FALSE;

	assert( attributeListHead == NULL || \
			isWritePtr( attributeListHead, sizeof( ATTRIBUTE_LIST ) ) );
	assert( attributeListCursor == NULL || \
			isWritePtr( attributeListCursor, sizeof( ATTRIBUTE_LIST ) ) );
	assert( ( sessionInfoType == CRYPT_ATTRIBUTE_CURRENT ) || \
			( sessionInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP ) || \
			( sessionInfoType > CRYPT_SESSINFO_FIRST && \
			  sessionInfoType < CRYPT_SESSINFO_LAST ) );
	assert( isWritePtr( valuePtr, sizeof( int ) ) );

	/* Clear return value */
	*valuePtr = CRYPT_ATTRIBUTE_NONE;

	/* We're querying something that resides in the attribute list, make 
	   sure that there's an attribute list present.  If it's present but 
	   nothing is selected, select the first entry */
	if( attributeListCursor == NULL )
		{
		if( attributeListHead == NULL )
			return( CRYPT_ERROR_NOTFOUND );
		attributeListCursor = attributeListHead;
		resetVirtualCursor( attributeListCursor );
		initAttributeList = TRUE;
		}

	/* If we're reading the group, return the group type */
	if( sessionInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP ) 
		*valuePtr = attributeListCursor->groupID;
	else
		/* If it's a single-attribute group, return the attribute type */
		if( !( attributeListCursor->flags & ATTR_FLAG_COMPOSITE ) )
			*valuePtr = attributeListCursor->groupID;
		else
			/* It's a composite type, get the currently-selected sub-attribute */
			*valuePtr = attributeListCursor->accessFunction( attributeListCursor, 
														 ATTR_NONE );
	return( initAttributeList ? OK_SPECIAL : CRYPT_OK );
	}

int setSessionAttributeCursor( ATTRIBUTE_LIST *attributeListHead,
							   ATTRIBUTE_LIST **attributeListCursorPtr, 
							   const CRYPT_ATTRIBUTE_TYPE sessionInfoType,
							   const int position )
	{
	ATTRIBUTE_LIST *attributeListPtr = *attributeListCursorPtr;

	assert( attributeListHead == NULL || \
			isWritePtr( attributeListHead, sizeof( ATTRIBUTE_LIST ) ) );

⌨️ 快捷键说明

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