📄 ldap.c
字号:
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 + -