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

📄 cldapx509keyserver.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
字号:
/*____________________________________________________________________________
        Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: CLDAPX509KeyServer.cpp,v 1.11 2002/08/28 03:33:45 dallen Exp $
____________________________________________________________________________*/

#include "pgpConfig.h"
#include "CLDAPX509KeyServer.h"
#include "pgpEventPriv.h"
#include "pgpKeys.h"
#include "pgpUtilities.h"
#include "pgpMem.h"
#include "pgpX509Priv.h"


#define ThrowIfLDAPCanceled_()	if (mCanceled) \
									ThrowPGPError_(kPGPError_UserAbort);
#define ThrowIfPGPErrorOrLDAPCanceled_(x)	{	ThrowIfPGPError_(x); \
												ThrowIfLDAPCanceled_(); }

#define kPGPNamingContextsAttr		"namingContexts"
#define kPGPUserCertificateAttr		"userCertificate;binary"
#define kPGPEmptyBaseDN				""
#define kPGPObjectclassAny			"(objectclass=*)"


CLDAPX509KeyServer::CLDAPX509KeyServer(
	PGPContextRef				inContext,
	const char *				inHostName,
	PGPUInt32					inHostAddress,
	PGPUInt16					inHostPort,
	PGPKeyServerProtocol		inType,
	PGPKeyServerClass			inClass,
	PGPKeyServerAccessType		inAccessType )
	: CKeyServer( inContext, inHostName, inHostAddress, inHostPort, NULL, inType, inClass ),
	  mContext( inContext ),
	  mAccessType( inAccessType ), 
	  mLDAP( kInvalidPGPldapContextRef )
{
	return;
}


CLDAPX509KeyServer::~CLDAPX509KeyServer( )
{
	return;
}


	void
CLDAPX509KeyServer::Cancel( )
{
	CKeyServer::Cancel();

	if( !PGPldapContextRefIsValid( mLDAP ) )
		return;

	return;
}


	void
CLDAPX509KeyServer::Open(
	PGPtlsSessionRef )
{
	StPreserveSocketsEventHandler		preserve(this);
	PGPldapResult						result;
	char *								szError			= NULL;
	PGPError							err				= kPGPError_NoErr;

	SetErrorString( NULL );
	try
	{
		err = pgpEventKeyServer( mContext,
					mEventHandler,
					mEventHandlerData,
					(PGPKeyServerRef) this,
					kPGPKeyServerState_Opening );
		ThrowIfPGPErrorOrLDAPCanceled_( err );

		err = PGPNewLDAPContext( mContext, &mLDAP );
		if( !PGPldapContextRefIsValid( mLDAP ) || IsPGPError( err ) )
			ThrowPGPError_( kPGPError_ServerOpenFailed );

		err = PGPldapOpen( mLDAP, mHostName, mHostPort );
		ThrowIfLDAPCanceled_();

		if( IsPGPError( err ) )
			ThrowPGPError_( kPGPError_ServerOpenFailed );

		mIsOpen = true;
	}
	catch( ... )
	{
		mIsOpen = false;
		if( PGPldapContextRefIsValid( mLDAP ) )
		{
			if( !mCanceled )
			{
				(void) PGPldapGetErrno( mLDAP, NULL, &szError, &result );
				SetErrorString( szError );
			}
		}
		if( mCanceled )
		{
			mCanceled = false;
			ThrowPGPError_( kPGPError_UserAbort );
		}
		else
			throw;
	}

	return;
}


	void
CLDAPX509KeyServer::Close( )
{
	StPreserveSocketsEventHandler	preserve(this);

	(void) pgpEventKeyServer( mContext,
				mEventHandler,
				mEventHandlerData,
				(PGPKeyServerRef) this,
				kPGPKeyServerState_Closing);
						
	if( PGPldapContextRefIsValid( mLDAP ) )
	{
		(void) PGPldapUnbind( mLDAP );

		(void) PGPFreeLDAPContext( mLDAP );
		mLDAP = kInvalidPGPldapContextRef;
	}
	CKeyServer::Close();

	return;
}


	void
CLDAPX509KeyServer::Query(
	PGPFilterRef				inFilterRef,
	PGPKeyDBRef *				outFoundKeys )
{
	StPreserveSocketsEventHandler		preserve(this);

	PGPError					err				= kPGPError_NoErr;
	char *						query			= NULL;
	PGPldapMessageRef			firstMessage	= kInvalidPGPldapMessageRef;
	PGPldapMessageRef			currentMessage	= kInvalidPGPldapMessageRef;
	const char *				namingContextsAttrs[] = { kPGPNamingContextsAttr,
															NULL };
	const char *				userCertificateAttrs[] = { kPGPUserCertificateAttr,
															NULL };
	char **						namingContexts	= NULL;
	PGPUInt32					namingContextIndex	= 0;
	PGPberValue **				berValues		= NULL;
	PGPBoolean					receivedBadKeys	= false;
	PGPBoolean					partialResults	= false;
	PGPKeyDBRef					singleKeyDB		= kInvalidPGPKeyDBRef;
	PGPKeyDBRef					foundKeys		= kInvalidPGPKeyDBRef;
	PGPKeySetRef				singleKeySet	= kInvalidPGPKeySetRef;
	PGPUInt32					i				= 0;
	char *						szError			= NULL;
	PGPldapResult				ldapResult		= kPGPldapResult_Success;

	SetErrorString( NULL );
	if( !mIsOpen )
		ThrowPGPError_( kPGPError_ServerNotOpen );

	try
	{
		err = PGPLDAPX509QueryFromFilter( inFilterRef, &query );
		ThrowIfPGPErrorOrLDAPCanceled_( err );

		err = pgpEventKeyServer( mContext,
				mEventHandler,
				mEventHandlerData,
				(PGPKeyServerRef) this,
				kPGPKeyServerState_Querying );
		ThrowIfPGPErrorOrLDAPCanceled_( err );

		err = PGPNewLDAPMessage( mLDAP, &firstMessage );
		if( IsPGPError( err ) )
			ThrowPGPError_( kPGPError_ServerSearchFailed );

		err = PGPldapSearchSync( mLDAP,
				(char *) kPGPEmptyBaseDN,
				kPGPldapScope_Base,
				(char *) kPGPObjectclassAny,
				(char **) namingContextsAttrs,
				FALSE,
				firstMessage );
		if( IsPGPError( err ) )
			ThrowPGPError_( kPGPError_ServerSearchFailed );

		err = PGPldapGetValues( mLDAP,
				firstMessage,
				(char *) kPGPNamingContextsAttr,
				&namingContexts );
		if( IsPGPError( err ) )
			ThrowPGPError_( kPGPError_ServerSearchFailed );

		if( PGPldapMessageRefIsValid( firstMessage ) )
		{
			(void) PGPFreeLDAPMessage( firstMessage );
			firstMessage = kInvalidPGPldapMessageRef;
		}

		/*
		 * namingContexts now contains a set of base DNs the LDAP server
		 * can handle.  There is no way to tell which one is the one we
		 * want, so we have to check each one.
		 */

		err = PGPNewKeyDB( mContext, &foundKeys );
		ThrowIfPGPErrorOrLDAPCanceled_( err );

		for( namingContextIndex = 0; 
			IsntNull( namingContexts[namingContextIndex] );
			namingContextIndex++ )
		{
			err = PGPNewLDAPMessage( mLDAP, &firstMessage );
			if( IsPGPError( err ) )
				ThrowPGPError_( kPGPError_ServerSearchFailed );

			err = PGPldapSearchSync( mLDAP,
					namingContexts[namingContextIndex],
					kPGPldapScope_Subtree,
					query,
					(char **) userCertificateAttrs,
					FALSE,
					firstMessage );
			switch( err )
			{
				case kPGPError_NoErr:
					break;
				
				case kPGPError_LDAPInsufficientAccess:
					ThrowPGPError_( kPGPError_ServerAuthorizationFailed );
					break;
				
				case kPGPError_LDAPSizelimitExceeded:
				case kPGPError_LDAPTimelimitExceeded:
					partialResults = true;
					break;
				
				default:
					ThrowPGPError_(kPGPError_ServerSearchFailed);
					break;
			}

			/*
			 * firstMessage is now a chain of PGPldapMessageRefs, which contain 
			 * entries with attribute userCertificate;binary, each containing
			 * various x.509 certificates.
			 */

			err = PGPldapFirstEntry( mLDAP, firstMessage, &currentMessage );
			if( IsPGPError( err ) )
				ThrowPGPError_( kPGPError_ServerSearchFailed );

			while( PGPldapMessageRefIsValid( currentMessage ) )
			{
				err = PGPldapGetValuesLen( mLDAP,
						currentMessage,
						(char *) kPGPUserCertificateAttr,
						&berValues );
				if( err != kPGPError_LDAPNoSuchAttribute )
				{
					if( IsPGPError( err ) )
						ThrowPGPError_( kPGPError_ServerSearchFailed );

					for( i = 0; IsntNull( berValues[i] ); i++ )
					{
						err = PGPImport( mContext,
								&singleKeyDB,
								PGPOInputBuffer( mContext,
									berValues[i]->value,
									berValues[i]->length ),
								PGPOInputFormat( mContext,
									kPGPInputFormat_X509DataInPKCS7 ),
								PGPOLastOption( mContext ) );
						if( IsPGPError( err ) )
							receivedBadKeys = true;
						else
						{
							err = PGPNewKeySet( singleKeyDB, &singleKeySet );
							ThrowIfPGPError_( err );

							err = PGPCopyKeys( singleKeySet, foundKeys, NULL );
							ThrowIfPGPError_( err );

							(void) PGPFreeKeySet( singleKeySet );
							singleKeySet = kInvalidPGPKeySetRef;

							(void) PGPFreeKeyDB( singleKeyDB );
							singleKeyDB = kInvalidPGPKeyDBRef;
						}
					}

					(void) PGPFreeLDAPValuesLen( berValues );
					berValues = NULL;
				}

				err = PGPldapNextEntry( mLDAP, currentMessage, &currentMessage );
				if( IsPGPError( err ) )
					ThrowPGPError_( kPGPError_ServerSearchFailed );
			}

			if( PGPldapMessageRefIsValid( firstMessage ) )
			{
				(void) PGPFreeLDAPMessage( firstMessage );
				firstMessage = kInvalidPGPldapMessageRef;
			}
		}

		*outFoundKeys = foundKeys;


		if( PGPldapMessageRefIsValid( firstMessage ) )
		{
			(void) PGPFreeLDAPMessage( firstMessage );
			firstMessage = kInvalidPGPldapMessageRef;
		}

		if( IsntNull( namingContexts ) )
			(void) PGPFreeLDAPValues( namingContexts );

		if( IsntNull( berValues ) )
			(void) PGPFreeLDAPValuesLen( berValues );

		if( IsntNull( query ) )
			(void) PGPFreeData( query );
		
	}
	catch( ... )
	{
		if( PGPKeySetRefIsValid( singleKeySet ) )
			(void) PGPFreeKeySet( singleKeySet );

		if( PGPKeyDBRefIsValid( singleKeyDB ) )
			(void) PGPFreeKeyDB( singleKeyDB );

		if( PGPKeyDBRefIsValid( foundKeys ) )
			(void) PGPFreeKeyDB( foundKeys );

		if( PGPldapMessageRefIsValid( firstMessage ) )
			(void) PGPFreeLDAPMessage( firstMessage );

		if( IsntNull( namingContexts ) )
			(void) PGPFreeLDAPValues( namingContexts );

		if( IsntNull( berValues ) )
			(void) PGPFreeLDAPValuesLen( berValues );

		if( IsntNull( query ) )
			(void) PGPFreeData( query );

		if( mCanceled )
			ThrowPGPError_( kPGPError_UserAbort );
		else 
		{
			(void) PGPldapGetErrno( mLDAP, NULL, &szError, &ldapResult );
			SetErrorString( szError );
			throw;
		}
	}

	if( receivedBadKeys )
		ThrowPGPError_( kPGPError_ServerBadKeysInSearchResults );

	if( partialResults )
		ThrowPGPError_( kPGPError_ServerPartialSearchResults );

	return;
}






/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

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