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

📄 ldap.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
	   certificate attribute this can be switched over */
	if( ( ldapMod[ 0 ] = copyAttribute( ldapInfo->nameObjectClass,
										"certPerson", 0 ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	if( ( ldapMod[ ldapModIndex++ ] = copyAttribute( ldapInfo->nameCert,
										keyData, keyDataLength ) ) == NULL )
		status = CRYPT_ERROR_MEMORY;

	/* Set up the DN/identification information */
	if( cryptStatusOK( status ) && *email && \
		( ldapMod[ ldapModIndex++ ] = \
				copyAttribute( ldapInfo->nameEmail, email, 0 ) ) == NULL )
		status = CRYPT_ERROR_MEMORY;
	if( cryptStatusOK( status ) && *CN && \
		( ldapMod[ ldapModIndex++ ] = copyAttribute( "CN", CN, 0 ) ) == NULL )
		status = CRYPT_ERROR_MEMORY;
	if( cryptStatusOK( status ) && *OU && \
		( ldapMod[ ldapModIndex++ ] = copyAttribute( "OU", OU, 0 ) ) == NULL )
		status = CRYPT_ERROR_MEMORY;
	if( cryptStatusOK( status ) && *O && \
		( ldapMod[ ldapModIndex++ ] = copyAttribute( "O", O, 0 ) ) == NULL )
		status = CRYPT_ERROR_MEMORY;
	if( cryptStatusOK( status ) && *L && \
		( ldapMod[ ldapModIndex++ ] = copyAttribute( "L", L, 0 ) ) == NULL )
		status = CRYPT_ERROR_MEMORY;
	if( cryptStatusOK( status ) && *SP && \
		( ldapMod[ ldapModIndex++ ] = copyAttribute( "SP", SP, 0 ) ) == NULL )
		status = CRYPT_ERROR_MEMORY;
	if( cryptStatusOK( status ) && *C && \
		( ldapMod[ ldapModIndex++ ] = copyAttribute( "C", C, 0 ) ) == NULL )
		status = CRYPT_ERROR_MEMORY;
	ldapMod[ ldapModIndex ] = NULL;

	/* Add the new attribute/entry */
	if( cryptStatusOK( status ) )
		{
		int ldapStatus;

		if( ( ldapStatus = ldap_add_s( ldapInfo->ld, dn,
									   ldapMod ) ) != LDAP_SUCCESS )
			{
			getErrorInfo( keysetInfoPtr, ldapStatus );
			status = mapLdapError( ldapStatus, CRYPT_ERROR_WRITE );
			}
		}

	/* Clean up.  We do it the hard way rather than using
	   ldap_mods_free() here partially because the ldapMod[] array
	   isn't malloc()'d, but mostly because for the Netscape client
	   library ldap_mods_free() causes some sort of memory corruption,
	   possibly because it's trying to free the mod_values[] entries
	   which are statically allocated, and for the MS client the
	   function doesn't exist */
	for( ldapModIndex = 0; ldapMod[ ldapModIndex ] != NULL && \
						   ldapModIndex < MAX_LDAP_ATTRIBUTES;
		 ldapModIndex++ )
		{
		if( ldapMod[ ldapModIndex ]->mod_op & LDAP_MOD_BVALUES )
			clFree( "addCert", ldapMod[ ldapModIndex ]->mod_bvalues[ 0 ] );
		clFree( "addCert", ldapMod[ ldapModIndex ]->mod_values );
		clFree( "addCert", ldapMod[ ldapModIndex ] );
		}
	if( ldapModIndex >= MAX_LDAP_ATTRIBUTES )
		retIntError();
	return( status );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int setItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
							IN_HANDLE const CRYPT_HANDLE iCryptHandle,
							IN_ENUM( KEYMGMT_ITEM ) \
								const KEYMGMT_ITEM_TYPE itemType,
							STDC_UNUSED const char *password, 
							STDC_UNUSED const int passwordLength,
							IN_FLAGS( KEYMGMT ) const int flags )
	{
	BOOLEAN seenNonDuplicate = FALSE;
	int type, iterationCount = 0, status;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_LDAP );
	REQUIRES( isHandleRangeValid( iCryptHandle ) );
	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY );
	REQUIRES( password == NULL && passwordLength == 0 );
	REQUIRES( flags == KEYMGMT_FLAG_NONE );

	/* Make sure we've been given a certificate or certificate chain */
	status = krnlSendMessage( iCryptHandle, MESSAGE_GETATTRIBUTE, &type, 
							  CRYPT_CERTINFO_CERTTYPE );
	if( cryptStatusError( status ) )
		return( CRYPT_ARGERROR_NUM1 );
	if( type != CRYPT_CERTTYPE_CERTIFICATE && \
		type != CRYPT_CERTTYPE_CERTCHAIN )
		return( CRYPT_ARGERROR_NUM1 );

	/* Lock the certificate for our exclusive use (in case it's a 
	   certificate chain, we also select the first certificate in the 
	   chain), update the keyset with the certificate(s), and unlock it to 
	   allow others access */
	krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
					 MESSAGE_VALUE_CURSORFIRST,
					 CRYPT_CERTINFO_CURRENT_CERTIFICATE );
	status = krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_TRUE, CRYPT_IATTRIBUTE_LOCKED );
	if( cryptStatusError( status ) )
		return( status );
	do
		{
		/* Add the certificate */
		status = addCert( keysetInfoPtr, iCryptHandle );

		/* A certificate being added may already be present, however we 
		   can't fail immediately because what's being added may be a chain 
		   containing further certificates so we keep track of whether we've 
		   successfully added at least one certificate and clear data 
		   duplicate errors */
		if( status == CRYPT_OK )
			seenNonDuplicate = TRUE;
		else
			if( status == CRYPT_ERROR_DUPLICATE )
				status = CRYPT_OK;
		}
	while( cryptStatusOK( status ) && \
		   krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE,
							MESSAGE_VALUE_CURSORNEXT,
							CRYPT_CERTINFO_CURRENT_CERTIFICATE ) == CRYPT_OK && \
		   iterationCount++ < FAILSAFE_ITERATIONS_MED );
	if( iterationCount >= FAILSAFE_ITERATIONS_MED )
		retIntError();
	krnlSendMessage( iCryptHandle, IMESSAGE_SETATTRIBUTE, 
					 MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_LOCKED );
	if( cryptStatusOK( status ) && !seenNonDuplicate )
		/* We reached the end of the chain without finding anything we could
		   add, return a data duplicate error */
		status = CRYPT_ERROR_DUPLICATE;

	return( status );
	}

/* Delete an entry from an LDAP directory */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int deleteItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
							   IN_ENUM( KEYMGMT_ITEM ) \
								const KEYMGMT_ITEM_TYPE itemType,
							   IN_KEYID const CRYPT_KEYID_TYPE keyIDtype,
							   IN_BUFFER( keyIDlength ) const void *keyID, 
							   IN_LENGTH_KEYID const int keyIDlength )
	{
	LDAP_INFO *ldapInfo = keysetInfoPtr->keysetLDAP;
	char dn[ MAX_DN_STRINGSIZE + 8 ];
	int ldapStatus;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( isReadPtr( keyID, keyIDlength ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_LDAP );
	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY );
	REQUIRES( keyIDtype == CRYPT_KEYID_NAME || keyIDtype == CRYPT_KEYID_URI );
	REQUIRES( keyIDlength >= MIN_NAME_LENGTH && \
			  keyIDlength < MAX_ATTRIBUTE_SIZE );

	/* Convert the DN into a null-terminated form */
	if( keyIDlength > MAX_DN_STRINGSIZE - 1 )
		return( CRYPT_ARGERROR_STR1 );
	memcpy( dn, keyID, keyIDlength );
	dn[ keyIDlength ] = '\0';

	/* Delete the entry */
	if( ( ldapStatus = ldap_delete_s( ldapInfo->ld, dn ) ) != LDAP_SUCCESS )
		{
		getErrorInfo( keysetInfoPtr, ldapStatus );
		return( mapLdapError( ldapStatus, CRYPT_ERROR_WRITE ) );
		}

	return( CRYPT_OK );
	}

/* Perform a getFirst/getNext query on the LDAP directory */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 6 ) ) \
static int getFirstItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
								 OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate,
								 STDC_UNUSED int *stateInfo,
								 IN_ENUM( KEYMGMT_ITEM ) \
									const KEYMGMT_ITEM_TYPE itemType,
								 IN_KEYID const CRYPT_KEYID_TYPE keyIDtype,
								 IN_BUFFER( keyIDlength ) const void *keyID, 
								 IN_LENGTH_KEYID const int keyIDlength,
								 IN_FLAGS( KEYMGMT ) const int options )
	{
	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
	assert( isReadPtr( keyID, keyIDlength ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_LDAP );
	REQUIRES( stateInfo == NULL );
	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY );
	REQUIRES( keyIDtype != CRYPT_KEYID_NONE );
	REQUIRES( keyIDlength >= MIN_NAME_LENGTH && \
			  keyIDlength < MAX_ATTRIBUTE_SIZE );
	REQUIRES( options == KEYMGMT_FLAG_NONE );

	return( getItemFunction( keysetInfoPtr, NULL, KEYMGMT_ITEM_PUBLICKEY,
							 CRYPT_KEYID_NAME, keyID, keyIDlength, NULL,
							 0, 0 ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
static int getNextItemFunction( INOUT KEYSET_INFO *keysetInfoPtr,
								OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate,
								STDC_UNUSED int *stateInfo, 
								IN_FLAGS( KEYMGMT ) const int options )
	{
	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_LDAP );
	REQUIRES( stateInfo == NULL );
	REQUIRES( options == KEYMGMT_FLAG_NONE );

	return( getItemFunction( keysetInfoPtr, iCertificate, 
							 KEYMGMT_ITEM_PUBLICKEY, CRYPT_KEYID_NONE, 
							 NULL, 0, NULL, 0, 0 ) );
	}

/* Return status information for the keyset */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static BOOLEAN isBusyFunction( INOUT KEYSET_INFO *keysetInfoPtr )
	{
	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_LDAP );

	return( FALSE );
	}

/* Get/set keyset attributes */

static void *getAttributeDataPtr( KEYSET_INFO *keysetInfoPtr, 
								  const CRYPT_ATTRIBUTE_TYPE type )
	{
	LDAP_INFO *ldapInfo = keysetInfoPtr->keysetLDAP;

	switch( type )
		{
		case CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS:
			return( ldapInfo->nameObjectClass );

		case CRYPT_OPTION_KEYS_LDAP_FILTER:
			return( ldapInfo->nameFilter );

		case CRYPT_OPTION_KEYS_LDAP_CACERTNAME:
			return( ldapInfo->nameCACert );

		case CRYPT_OPTION_KEYS_LDAP_CERTNAME:
			return( ldapInfo->nameCert );

		case CRYPT_OPTION_KEYS_LDAP_CRLNAME:
			return( ldapInfo->nameCRL );

		case CRYPT_OPTION_KEYS_LDAP_EMAILNAME:
			return( ldapInfo->nameEmail );
		}

	return( NULL );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int getAttributeFunction( INOUT KEYSET_INFO *keysetInfoPtr, 
								 OUT void *data,
								 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE type )
	{
	const void *attributeDataPtr;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_LDAP );

	attributeDataPtr = getAttributeDataPtr( keysetInfoPtr, type );
	if( attributeDataPtr == NULL )
		return( CRYPT_ARGERROR_VALUE );
	return( attributeCopy( data, attributeDataPtr, 
						   strlen( attributeDataPtr ) ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int setAttributeFunction( INOUT KEYSET_INFO *keysetInfoPtr, 
								 const void *data,
								 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE type )
	{
	const MESSAGE_DATA *msgData = ( MESSAGE_DATA * ) data;
	BYTE *attributeDataPtr;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_LDAP );

	attributeDataPtr = getAttributeDataPtr( keysetInfoPtr, type );
	if( attributeDataPtr == NULL )
		return( CRYPT_ARGERROR_VALUE );
	if( msgData->length < 1 || msgData->length > CRYPT_MAX_TEXTSIZE )
		return( CRYPT_ARGERROR_STR1 );
	memcpy( attributeDataPtr, msgData->data, msgData->length );
	attributeDataPtr[ msgData->length ] = '\0';

	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int setAccessMethodLDAP( INOUT KEYSET_INFO *keysetInfoPtr )
	{
	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_LDAP );

#ifdef DYNAMIC_LOAD
	/* Make sure that the LDAP driver is bound in */
	if( hLDAP == NULL_INSTANCE )
		return( CRYPT_ERROR_OPEN );
#endif /* DYNAMIC_LOAD */

	/* Set the access method pointers */
	keysetInfoPtr->initFunction = initFunction;
	keysetInfoPtr->shutdownFunction = shutdownFunction;
	keysetInfoPtr->getAttributeFunction = getAttributeFunction;
	keysetInfoPtr->setAttributeFunction = setAttributeFunction;
	keysetInfoPtr->getItemFunction = getItemFunction;
	keysetInfoPtr->setItemFunction = setItemFunction;
	keysetInfoPtr->deleteItemFunction = deleteItemFunction;
	keysetInfoPtr->getFirstItemFunction = getFirstItemFunction;
	keysetInfoPtr->getNextItemFunction = getNextItemFunction;
	keysetInfoPtr->isBusyFunction = isBusyFunction;

	return( CRYPT_OK );
	}
#endif /* USE_LDAP */

⌨️ 快捷键说明

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