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

📄 sess_attr.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
														value, attribute );
				if( cryptStatusError( status ) )
					return( status );
				}

			/* Add the private key and increment its reference count */
			krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
			sessionInfoPtr->privateKey = value;

			return( CRYPT_OK );
			}

		case CRYPT_SESSINFO_KEYSET:
			{
			int type;

			/* Make sure that it's either a certificate store (rather than 
			   just a generic keyset) if required, or specifically not a 
			   certificate store if not required.  This is to prevent a 
			   session running with unnecessary privileges, we should only 
			   be using a certificate store if it's actually required.  The 
			   checking is already performed by the kernel, but we do it 
			   again here just to be safe */
			status = krnlSendMessage( value, IMESSAGE_GETATTRIBUTE, &type, 
									  CRYPT_IATTRIBUTE_SUBTYPE );
			if( cryptStatusError( status ) )
				return( CRYPT_ARGERROR_NUM1 );
			if( sessionInfoPtr->serverReqAttrFlags & SESSION_NEEDS_CERTSTORE )
				{
				if( type != SUBTYPE_KEYSET_DBMS_STORE )
					return( CRYPT_ARGERROR_NUM1 );
				}
			else
				{
				if( type != SUBTYPE_KEYSET_DBMS )
					return( CRYPT_ARGERROR_NUM1 );
				}

			/* Add the keyset and increment its reference count */
			krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
			sessionInfoPtr->cryptKeyset = value;

			return( CRYPT_OK );
			}

		case CRYPT_SESSINFO_AUTHRESPONSE:
			sessionInfoPtr->authResponse = value;
			return( CRYPT_OK );

		case CRYPT_SESSINFO_SESSION:
			/* If there's already a host or network socket specified we 
			   can't set a transport session as well */
			if( findSessionInfo( sessionInfoPtr->attributeList,
								 CRYPT_SESSINFO_SERVER_NAME ) != NULL )
				return( exitErrorInited( sessionInfoPtr,
										 CRYPT_SESSINFO_SERVER_NAME ) );
			if( sessionInfoPtr->networkSocket != CRYPT_ERROR )
				return( exitErrorInited( sessionInfoPtr,
										 CRYPT_SESSINFO_NETWORKSOCKET ) );

			/* Add the transport mechanism and increment its reference
			   count */
			krnlSendNotifier( value, IMESSAGE_INCREFCOUNT );
			sessionInfoPtr->transportSession = value;

			return( CRYPT_OK );

		case CRYPT_SESSINFO_NETWORKSOCKET:
			{
			NET_CONNECT_INFO connectInfo;
			STREAM stream;

			/* If there's already a host or session specified we can't set a 
			   network socket as well */
			if( findSessionInfo( sessionInfoPtr->attributeList,
								 CRYPT_SESSINFO_SERVER_NAME ) != NULL )
				return( exitErrorInited( sessionInfoPtr,
										 CRYPT_SESSINFO_SERVER_NAME ) );
			if( sessionInfoPtr->transportSession != CRYPT_ERROR )
				return( exitErrorInited( sessionInfoPtr,
										 CRYPT_SESSINFO_SESSION ) );

			/* Create a dummy network stream to make sure that the network 
			   socket is OK */
			initNetConnectInfo( &connectInfo, sessionInfoPtr->ownerHandle, 
								sessionInfoPtr->readTimeout, 
								sessionInfoPtr->connectTimeout,
								NET_OPTION_NETWORKSOCKET_DUMMY );
			connectInfo.networkSocket = value;
			status = sNetConnect( &stream, STREAM_PROTOCOL_TCPIP, 
								  &connectInfo, &sessionInfoPtr->errorInfo );
			if( cryptStatusError( status ) )
				return( status );
			sNetDisconnect( &stream );

			/* Add the network socket */
			sessionInfoPtr->networkSocket = value;

			return( CRYPT_OK );
			}
		}

	retIntError();
	}

/* Set a string attribute */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
int setSessionAttributeS( INOUT SESSION_INFO *sessionInfoPtr,
						  IN_BUFFER( dataLength ) const void *data,
						  IN_LENGTH const int dataLength,
						  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
	{
	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
	assert( isReadPtr( data, dataLength ) );

	/* If we're in the middle of a paired-attribute add, make sure that the
	   conditions under which it's occurring are valid */
	if( sessionInfoPtr->lastAddedAttributeID != CRYPT_ATTRIBUTE_NONE )
		{
		switch( sessionInfoPtr->lastAddedAttributeID )
			{
			case CRYPT_SESSINFO_USERNAME:
				/* Username must be followed by a password */
				if( attribute != CRYPT_SESSINFO_PASSWORD )
					return( CRYPT_ARGERROR_VALUE );
				break;

			default:
				retIntError();
			}
		}

	/* Handle the various information types */
	switch( attribute )
		{
		case CRYPT_OPTION_NET_SOCKS_SERVER:
		case CRYPT_OPTION_NET_SOCKS_USERNAME:
		case CRYPT_OPTION_NET_HTTP_PROXY:
			/* These aren't implemented on a per-session level yet since 
			   they're almost never used */
			return( CRYPT_ARGERROR_VALUE );

		case CRYPT_SESSINFO_USERNAME:
		case CRYPT_SESSINFO_PASSWORD:
			{
			int flags = isServer( sessionInfoPtr ) ? \
						ATTR_FLAG_MULTIVALUED : ATTR_FLAG_NONE;
			int status;

			REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );

			/* If this is a client session we can only have a single 
			   instance of this attribute */
			if( !isServer( sessionInfoPtr ) && \
				findSessionInfo( sessionInfoPtr->attributeList, 
								 attribute ) != NULL )
				return( exitErrorInited( sessionInfoPtr, attribute ) );
				
			/* If it's a username, make sure that it doesn't duplicate an
			   existing one */
			if( attribute == CRYPT_SESSINFO_USERNAME )
				{
				if( findSessionInfoEx( sessionInfoPtr->attributeList, 
									   attribute, data, dataLength ) != NULL )
					return( exitError( sessionInfoPtr, attribute,
									   CRYPT_ERRTYPE_ATTR_PRESENT, 
									   CRYPT_ERROR_DUPLICATE ) );
				}
			else
				{
				/* It's a password, make sure that there's an associated
				   username to go with it.  There are two approaches that
				   we can take here, the first simply requires that the
				   current cursor position is a username, implying that
				   the last-added attribute was a username.  The other is
				   to try and move the cursor to the last username in the
				   attribute list and check that the next attribute isn't
				   a password and then add it there, however this is doing
				   a bit too much behind the user's back, is somewhat 
				   difficult to back out of, and leads to exceptions to
				   exceptions, so we keep it simple and only allow passwords
				   to be added if there's an immediately preceding
				   username */
				if( sessionInfoPtr->lastAddedAttributeID != CRYPT_SESSINFO_USERNAME )
					return( exitErrorNotInited( sessionInfoPtr, 
												CRYPT_SESSINFO_USERNAME ) );
				}

			/* If it could be an encoded PKI value, check its validity */
			if( dataLength >= 15 && isPKIUserValue( data, dataLength ) )
				{
				BYTE decodedValue[ CRYPT_MAX_TEXTSIZE + 8 ];
				int decodedValueLen;

				/* It's an encoded value, make sure that it's in order */
				status = decodePKIUserValue( decodedValue, 
											 CRYPT_MAX_TEXTSIZE, 
											 &decodedValueLen, data, 
											 dataLength );
				zeroise( decodedValue, CRYPT_MAX_TEXTSIZE );
				if( cryptStatusError( status ) )
					return( status );
				flags = ATTR_FLAG_ENCODEDVALUE;
				}

			/* Remember the value */
			status = addSessionInfoEx( &sessionInfoPtr->attributeList,
									   attribute, data, dataLength, flags );
			if( cryptStatusError( status ) )
				return( status );
			sessionInfoPtr->lastAddedAttributeID = \
							( attribute == CRYPT_SESSINFO_USERNAME ) ? \
							CRYPT_SESSINFO_USERNAME : CRYPT_ATTRIBUTE_NONE;
			return( CRYPT_OK );
			}

		case CRYPT_SESSINFO_SERVER_FINGERPRINT:
			/* Remember the value */
			return( addSessionInfo( &sessionInfoPtr->attributeList,
									attribute, data, dataLength ) );

		case CRYPT_SESSINFO_SERVER_NAME:
			return( addUrl( sessionInfoPtr, data, dataLength ) );
		}

	retIntError();
	}

/****************************************************************************
*																			*
*								Delete Attributes							*
*																			*
****************************************************************************/

/* Delete an attribute */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int deleteSessionAttribute( INOUT SESSION_INFO *sessionInfoPtr,
							IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
	{
	const ATTRIBUTE_LIST *attributeListPtr;

	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );

	REQUIRES( isAttribute( attribute ) || \
			  isInternalAttribute( attribute ) );

	/* Handle the various information types */
	switch( attribute )
		{
		case CRYPT_OPTION_NET_CONNECTTIMEOUT:
			if( sessionInfoPtr->connectTimeout == CRYPT_ERROR )
				return( exitErrorNotFound( sessionInfoPtr,
										   CRYPT_OPTION_NET_CONNECTTIMEOUT ) );
			sessionInfoPtr->connectTimeout = CRYPT_ERROR;
			return( CRYPT_OK );

		case CRYPT_OPTION_NET_READTIMEOUT:
			if( sessionInfoPtr->readTimeout == CRYPT_ERROR )
				return( exitErrorNotFound( sessionInfoPtr,
										   CRYPT_OPTION_NET_READTIMEOUT ) );
			sessionInfoPtr->readTimeout = CRYPT_ERROR;
			return( CRYPT_OK );

		case CRYPT_OPTION_NET_WRITETIMEOUT:
			if( sessionInfoPtr->writeTimeout == CRYPT_ERROR )
				return( exitErrorNotFound( sessionInfoPtr,
										   CRYPT_OPTION_NET_WRITETIMEOUT ) );
			sessionInfoPtr->writeTimeout = CRYPT_ERROR;
			return( CRYPT_OK );

		case CRYPT_SESSINFO_USERNAME:
		case CRYPT_SESSINFO_PASSWORD:
		case CRYPT_SESSINFO_SERVER_NAME:
		case CRYPT_SESSINFO_SERVER_PORT:
			/* Make sure that the attribute to delete is actually present */
			attributeListPtr = \
				findSessionInfo( sessionInfoPtr->attributeList, attribute );
			if( attributeListPtr == NULL )
				return( exitErrorNotFound( sessionInfoPtr, attribute ) );

			/* If we're in the middle of a paired-attribute add and the 
			   delete affects the paired attribute, delete it.  This can
			   get quite complex because the user could (for example) add
			   a { username, password } pair, then add a second username
			   (but not password), and then delete the first password, which
			   will reset the lastAddedAttributeID, leaving an orphaned
			   password followed by an orphaned username.  There isn't any
			   easy way to fix this short of forcing some form of group 
			   delete of paired attributes, but this gets too complicated
			   both to implement and to explain to the user in an error
			   status.  What we do here is handle the simple case and let
			   the pre-session-activation sanity check catch situations 
			   where the user's gone out of their way to be difficult */
			if( sessionInfoPtr->lastAddedAttributeID == attribute )
				sessionInfoPtr->lastAddedAttributeID = CRYPT_ATTRIBUTE_NONE;

			/* Delete the attribute */
			deleteSessionInfo( &sessionInfoPtr->attributeList,
							   &sessionInfoPtr->attributeListCurrent,
							   ( ATTRIBUTE_LIST * ) attributeListPtr );
			return( CRYPT_OK );

		case CRYPT_SESSINFO_REQUEST:
			if( sessionInfoPtr->iCertRequest == CRYPT_ERROR )
				return( exitErrorNotFound( sessionInfoPtr,
										   CRYPT_SESSINFO_REQUEST ) );
			krnlSendNotifier( sessionInfoPtr->iCertRequest,
							  IMESSAGE_DECREFCOUNT );
			sessionInfoPtr->iCertRequest = CRYPT_ERROR;

			return( CRYPT_OK );

		case CRYPT_SESSINFO_TSP_MSGIMPRINT:
			if( sessionInfoPtr->sessionTSP->imprintAlgo == CRYPT_ALGO_NONE || \
				sessionInfoPtr->sessionTSP->imprintSize <= 0 )
				return( exitErrorNotFound( sessionInfoPtr,
										   CRYPT_SESSINFO_TSP_MSGIMPRINT ) );
			sessionInfoPtr->sessionTSP->imprintAlgo = CRYPT_ALGO_NONE;
			sessionInfoPtr->sessionTSP->imprintSize = 0;

			return( CRYPT_OK );
		}

	retIntError();
	}

#endif /* USE_SESSIONS */

⌨️ 快捷键说明

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